[for review] Changes to config and bytecode (again!)
Bert Thompson
aet at cs.mu.oz.au
Sat Apr 12 18:52:53 AEST 1997
Zoltan,
Can you please review these changes...
Bert
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Estimated hours taken: 2
We added to mercury_types.h the type Float64, which is a 64-bit IEEE-754
floating point type that may be either big-endian or little-endian.
In order to do this, we also added a test in configure.in to see if
the C type `double' is 64-bit on the platform.
Another test added to configure.in is the platform endianness.
We need this in order to dump a float to bytecode in a manner portable
between all platforms on which we're interested in running Mercury.
We also change output_float and output_int in compiler/bytecode.m
to dump floats and ints respectively in a portable way.
In compiler/bytecode.m, we also make a gratuitous renaming of
output_two_byte() to output_short(). All uses of output_two_byte()
were effectively to dump a short.
configure.in
runtime/
conf.h.in
mercury_types.h
compiler/
bytecode.m
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Index: configure.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/configure.in,v
retrieving revision 1.88
diff -c -r1.88 configure.in
*** configure.in 1997/03/27 09:13:35 1.88
--- configure.in 1997/04/10 09:14:42
***************
*** 760,765 ****
--- 760,833 ----
fi
AC_SUBST(HAVE_BOXED_FLOATS)
#-----------------------------------------------------------------------------#
+ AC_MSG_CHECKING(whether double is 64-bits)
+ AC_CACHE_VAL(mercury_cv_float64,
+ AC_TRY_RUN([
+ #include <limits.h>
+ int main() {
+ if (sizeof(double) * CHAR_BIT == 64)
+ exit(0);
+ else
+ exit(1);
+ }],
+ [mercury_cv_float64=yes],
+ [mercury_cv_float64=no],
+ [mercury_cv_float64=no])
+ )
+ AC_MSG_RESULT($mercury_cv_float64)
+ if test "$mercury_cv_float64" = yes; then
+ AC_DEFINE(DOUBLE_IS_64_BITS)
+ fi
+ AC_SUBST(DOUBLE_IS_64_BITS)
+ #-----------------------------------------------------------------------------#
+ AC_MSG_CHECKING(whether architecture is big-endian)
+ AC_CACHE_VAL(mercury_is_bigender,
+ AC_TRY_RUN([
+ int main() {
+ int x = 1;
+ unsigned char *x_p;
+
+ x_p = (unsigned char*) &x;
+
+ if (*x_p == 0)
+ exit(0);
+ else
+ exit(1);
+ }],
+ [mercury_is_bigender=yes],
+ [mercury_is_bigender=no],
+ [mercury_is_bigender=no])
+ )
+ AC_MSG_RESULT($mercury_is_bigender)
+ if test "$mercury_is_bigender" = yes; then
+ AC_DEFINE(BIG_ENDIAN)
+ fi
+ AC_SUBST(BIG_ENDIAN)
+ #-----------------------------------------------------------------------------#
+ AC_MSG_CHECKING(whether architecture is little-endian)
+ AC_CACHE_VAL(mercury_is_littleender,
+ AC_TRY_RUN([
+ int main() {
+ int x = 1;
+ unsigned char *x_p;
+
+ x_p = (unsigned char*) &x;
+
+ if (*x_p == 1)
+ exit(0);
+ else
+ exit(1);
+ }],
+ [mercury_is_littleender=yes],
+ [mercury_is_littleender=no],
+ [mercury_is_littleender=no])
+ )
+ AC_MSG_RESULT($mercury_is_littleender)
+ if test "$mercury_is_littleender" = yes; then
+ AC_DEFINE(LITTLE_ENDIAN)
+ fi
+ AC_SUBST(LITTLE_ENDIAN)
+ #-----------------------------------------------------------------------------#
#
# For Irix 5, gcc labels don't work with shared libraries,
# so if we're using gcc labels, we need to use non-shared libraries,
Index: compiler/bytecode.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/bytecode.m,v
retrieving revision 1.23
diff -c -r1.23 bytecode.m
*** bytecode.m 1997/03/24 06:00:57 1.23
--- bytecode.m 1997/04/12 08:23:49
***************
*** 121,131 ****
:- implementation.
:- import_module hlds_pred.
! :- import_module char, library, int, string, require.
:- pred bytecode__version(int::out) is det.
! bytecode__version(8).
output_bytecode_file(FileName, ByteCodes) -->
io__tell_binary(FileName, Result),
--- 121,131 ----
:- implementation.
:- import_module hlds_pred.
! :- import_module char, library, int, string, require, globals, options.
:- pred bytecode__version(int::out) is det.
! bytecode__version(9).
output_bytecode_file(FileName, ByteCodes) -->
io__tell_binary(FileName, Result),
***************
*** 133,139 ****
{ Result = ok }
->
{ bytecode__version(Version) },
! output_two_byte(Version),
output_bytecode_list(ByteCodes),
io__told_binary
;
--- 133,139 ----
{ Result = ok }
->
{ bytecode__version(Version) },
! output_short(Version),
output_bytecode_list(ByteCodes),
io__told_binary
;
***************
*** 152,157 ****
--- 152,158 ----
{ Result = ok }
->
{ bytecode__version(Version) },
+ io__write_string("bytecode_version "),
io__write_int(Version),
io__write_string("\n"),
debug_bytecode_list(ByteCodes),
***************
*** 303,309 ****
output_args(semidet_success_check) --> [].
output_args(fail) --> [].
output_args(context(Line)) -->
! output_two_byte(Line).
output_args(not_supported) --> [].
:- pred debug_args(byte_code, io__state, io__state).
--- 304,310 ----
output_args(semidet_success_check) --> [].
output_args(fail) --> [].
output_args(context(Line)) -->
! output_short(Line).
output_args(not_supported) --> [].
:- pred debug_args(byte_code, io__state, io__state).
***************
*** 495,501 ****
:- mode output_length(in, di, uo) is det.
output_length(Length) -->
! output_two_byte(Length).
:- pred debug_length(int, io__state, io__state).
:- mode debug_length(in, di, uo) is det.
--- 496,502 ----
:- mode output_length(in, di, uo) is det.
output_length(Length) -->
! output_short(Length).
:- pred debug_length(int, io__state, io__state).
:- mode debug_length(in, di, uo) is det.
***************
*** 537,543 ****
:- mode output_var(in, di, uo) is det.
output_var(Var) -->
! output_two_byte(Var).
:- pred output_vars(list(byte_var), io__state, io__state).
:- mode output_vars(in, di, uo) is det.
--- 538,544 ----
:- mode output_var(in, di, uo) is det.
output_var(Var) -->
! output_short(Var).
:- pred output_vars(list(byte_var), io__state, io__state).
:- mode output_vars(in, di, uo) is det.
***************
*** 567,573 ****
:- mode output_temp(in, di, uo) is det.
output_temp(Var) -->
! output_two_byte(Var).
:- pred debug_temp(byte_temp, io__state, io__state).
:- mode debug_temp(in, di, uo) is det.
--- 568,574 ----
:- mode output_temp(in, di, uo) is det.
output_temp(Var) -->
! output_short(Var).
:- pred debug_temp(byte_temp, io__state, io__state).
:- mode debug_temp(in, di, uo) is det.
***************
*** 665,671 ****
:- mode output_label_id(in, di, uo) is det.
output_label_id(LabelId) -->
! output_two_byte(LabelId).
:- pred debug_label_id(int, io__state, io__state).
:- mode debug_label_id(in, di, uo) is det.
--- 666,672 ----
:- mode output_label_id(in, di, uo) is det.
output_label_id(LabelId) -->
! output_short(LabelId).
:- pred debug_label_id(int, io__state, io__state).
:- mode debug_label_id(in, di, uo) is det.
***************
*** 682,688 ****
output_byte(0),
output_string(ModuleId),
output_string(Functor),
! output_two_byte(Arity),
output_tag(Tag).
output_cons_id(int_const(IntVal)) -->
output_byte(1),
--- 683,689 ----
output_byte(0),
output_string(ModuleId),
output_string(Functor),
! output_short(Arity),
output_tag(Tag).
output_cons_id(int_const(IntVal)) -->
output_byte(1),
***************
*** 1086,1095 ****
{ error("byte does not fit in eight bits") }
).
! :- pred output_two_byte(int, io__state, io__state).
! :- mode output_two_byte(in, di, uo) is det.
! output_two_byte(Val) -->
{ Val1 is Val >> 8 },
{ Val2 is Val mod 256 },
( { Val1 < 256 } ->
--- 1087,1102 ----
{ error("byte does not fit in eight bits") }
).
! /*
! ** Spit out a `short' in a portable format.
! ** This format is: big-endian, 16-bit, 2's-complement.
! **
! ** NOTE: We -assume- the machine architecture uses 2's-complement.
! */
! :- pred output_short(int, io__state, io__state).
! :- mode output_short(in, di, uo) is det.
! output_short(Val) -->
{ Val1 is Val >> 8 },
{ Val2 is Val mod 256 },
( { Val1 < 256 } ->
***************
*** 1099,1132 ****
{ error("small integer does not fit in sixteen bits") }
).
:- pred output_int(int, io__state, io__state).
:- mode output_int(in, di, uo) is det.
output_int(Val) -->
! { Val1 is Val >> 24 },
! { Val2 is (Val >> 16) mod 256 },
! { Val3 is (Val >> 8) mod 256 },
! { Val4 is Val mod 256 },
! ( { Val1 < 256 } ->
io__write_byte(Val1),
io__write_byte(Val2),
io__write_byte(Val3),
! io__write_byte(Val4)
;
! { error("integer does not fit in thirtytwo bits") }
).
:- pred output_float(float, io__state, io__state).
:- mode output_float(in, di, uo) is det.
output_float(Val) -->
! % XXX This is just temporary; we ought to find a way to write out
! % the float as a sequence of bytes. Requiring the compiling and
! % debugging platform to have the same FP representation is better
! % than silently rounding/truncating float values given to the
! % debugger.
! { string__float_to_string(Val, Str) },
! output_string(Str).
%---------------------------------------------------------------------------%
--- 1106,1227 ----
{ error("small integer does not fit in sixteen bits") }
).
+ /*
+ ** Spit out an `int' in a portable `highest common denominator' format.
+ ** This format is: big-endian, 64-bit, 2's-complement int.
+ **
+ ** NOTE: We -assume- the mahcine architecture uses 2's-complement.
+ */
:- pred output_int(int, io__state, io__state).
:- mode output_int(in, di, uo) is det.
output_int(Val) -->
! globals__io_lookup_int_option(bytes_per_word, IntBytes),
! % Is Integer 32-bits?
! ( { IntBytes = 4 } ->
! io__write_byte(0),
! io__write_byte(0),
! io__write_byte(0),
! io__write_byte(0),
! { Val0 is (Val >> 24) mod 256 },
! { Val1 is (Val >> 16) mod 256 },
! { Val2 is (Val >> 8) mod 256 },
! { Val3 is (Val >> 0) mod 256 },
! io__write_byte(Val0),
! io__write_byte(Val1),
! io__write_byte(Val2),
! io__write_byte(Val3)
! % Is Integer 64-bits?
! ; { IntBytes = 8 } ->
! {Val0 is (Val >> 56) mod 256 },
! {Val1 is (Val >> 48) mod 256 },
! {Val2 is (Val >> 40) mod 256 },
! {Val3 is (Val >> 32) mod 256 },
! {Val4 is (Val >> 24) mod 256 },
! {Val5 is (Val >> 16) mod 256 },
! {Val6 is (Val >> 8) mod 256 },
! {Val7 is (Val >> 0) mod 256 },
! io__write_byte(Val0),
io__write_byte(Val1),
io__write_byte(Val2),
io__write_byte(Val3),
! io__write_byte(Val4),
! io__write_byte(Val5),
! io__write_byte(Val6),
! io__write_byte(Val7)
;
! /*
! ** XXX: We currently have no interest in architectures
! ** where int is neither 32- nor 64-bit.
! */
! { error("integer is neither 32 nor 64 bits") }
).
+
+ /*
+ ** Spit out a `float' in a portable `highest common denominator format.
+ ** This format is: big-endian, 64-bit, IEEE-754 floating point value.
+ **
+ ** NOTE: We -assume- the machine architecture uses IEEE-754.
+ */
:- pred output_float(float, io__state, io__state).
:- mode output_float(in, di, uo) is det.
output_float(Val) -->
! { float_to_float64_bytes(Val, B0, B1, B2, B3, B4, B5, B6, B7) },
! output_byte(B0),
! output_byte(B1),
! output_byte(B2),
! output_byte(B3),
! output_byte(B4),
! output_byte(B5),
! output_byte(B6),
! output_byte(B7).
!
! /*
! ** Convert a `float' to the representation used in the bytecode.
! ** That is, a sequence of eight bytes.
! */
! :- pred float_to_float64_bytes(float::in,
! int::out, int::out, int::out, int::out,
! int::out, int::out, int::out, int::out) is det.
! :- pragma(c_code,
! float_to_float64_bytes(FloatVal::in, B0::out, B1::out, B2::out, B3::out,
! B4::out, B5::out, B6::out, B7::out),
! "
!
! {
! Float64 float64;
! unsigned char *raw_mem_p;
!
! float64 = (Float64) FloatVal;
! raw_mem_p = (unsigned char*) &float64;
!
! #if defined(BIG_ENDIAN)
! B0 = *(raw_mem_p+0);
! B1 = *(raw_mem_p+1);
! B2 = *(raw_mem_p+2);
! B3 = *(raw_mem_p+3);
! B4 = *(raw_mem_p+4);
! B5 = *(raw_mem_p+5);
! B6 = *(raw_mem_p+6);
! B7 = *(raw_mem_p+7);
! #elif defined(LITTLE_ENDIAN)
! B7 = *(raw_mem_p+0);
! B6 = *(raw_mem_p+1);
! B5 = *(raw_mem_p+2);
! B4 = *(raw_mem_p+3);
! B3 = *(raw_mem_p+4);
! B2 = *(raw_mem_p+5);
! B1 = *(raw_mem_p+6);
! B0 = *(raw_mem_p+7);
! #else
! #error Weird-endian architecture
! #endif
! }
!
! "
! ).
%---------------------------------------------------------------------------%
Index: runtime/conf.h.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/conf.h.in,v
retrieving revision 1.13
diff -c -r1.13 conf.h.in
*** conf.h.in 1997/02/27 05:45:02 1.13
--- conf.h.in 1997/04/10 09:14:56
***************
*** 81,85 ****
--- 81,88 ----
#undef HAVE_SIGACTION
#undef SIGACTION_FIELD
#undef PARALLEL
+ #undef DOUBLE_IS_64_BITS
+ #undef BIG_ENDIAN
+ #undef LITTLE_ENDIAN
#endif /* CONF_H */
Index: runtime/mercury_types.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_types.h,v
retrieving revision 1.2
diff -c -r1.2 mercury_types.h
*** mercury_types.h 1997/02/12 02:15:57 1.2
--- mercury_types.h 1997/04/12 08:30:06
***************
*** 24,29 ****
--- 24,40 ----
typedef unsigned WORD_TYPE Unsigned;
typedef void Code; /* code addresses are `void *' */
+ /*
+ ** Float64 is required for the bytecode.
+ */
+
+ #if DOUBLE_IS_64_BITS
+ typedef double Float64;
+ #else
+ #error For Mercury bytecode, we require double to be 64-bit IEEE-754.
+ #endif
+
+
/* continuation function type, for --high-level-C option */
typedef void (*Cont) (void);
More information about the developers
mailing list