00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "f77-fcn.h"
00028 #include "lo-error.h"
00029 #include "mach-info.h"
00030 #include "singleton-cleanup.h"
00031
00032 extern "C"
00033 {
00034 double F77_FUNC (d1mach, D1MACH) (const octave_idx_type&);
00035 }
00036
00037 oct_mach_info *oct_mach_info::instance = 0;
00038
00039 union equiv
00040 {
00041 double d;
00042 int i[2];
00043 };
00044
00045 struct
00046 float_params
00047 {
00048 oct_mach_info::float_format fp_fmt;
00049 equiv fp_par[4];
00050 };
00051
00052 #define INIT_FLT_PAR(fp, fmt, sm1, sm2, lrg1, lrg2, rt1, rt2, dv1, dv2) \
00053 do \
00054 { \
00055 fp.fp_fmt = (fmt); \
00056 fp.fp_par[0].i[0] = (sm1); fp.fp_par[0].i[1] = (sm2); \
00057 fp.fp_par[1].i[0] = (lrg1); fp.fp_par[1].i[1] = (lrg2); \
00058 fp.fp_par[2].i[0] = (rt1); fp.fp_par[2].i[1] = (rt2); \
00059 fp.fp_par[3].i[0] = (dv1); fp.fp_par[3].i[1] = (dv2); \
00060 } \
00061 while (0)
00062
00063 static int
00064 equiv_compare (const equiv *std, const equiv *v, int len)
00065 {
00066 int i;
00067 for (i = 0; i < len; i++)
00068 if (v[i].i[0] != std[i].i[0] || v[i].i[1] != std[i].i[1])
00069 return 0;
00070 return 1;
00071 }
00072
00073 static oct_mach_info::float_format
00074 get_float_format (void)
00075 {
00076 oct_mach_info::float_format retval = oct_mach_info::flt_fmt_unknown;
00077
00078 #if defined (CRAY)
00079
00080
00081
00082 native_float_fmt = oct_mach_info::flt_fmt_cray;
00083
00084 #else
00085
00086 float_params fp[5];
00087
00088 INIT_FLT_PAR (fp[0], oct_mach_info::flt_fmt_ieee_big_endian,
00089 1048576, 0,
00090 2146435071, -1,
00091 1017118720, 0,
00092 1018167296, 0);
00093
00094 INIT_FLT_PAR (fp[1], oct_mach_info::flt_fmt_ieee_little_endian,
00095 0, 1048576,
00096 -1, 2146435071,
00097 0, 1017118720,
00098 0, 1018167296);
00099
00100 INIT_FLT_PAR (fp[2], oct_mach_info::flt_fmt_vax_d,
00101 128, 0,
00102 -32769, -1,
00103 9344, 0,
00104 9344, 0);
00105
00106 INIT_FLT_PAR (fp[3], oct_mach_info::flt_fmt_vax_g,
00107 16, 0,
00108 -32769, -1,
00109 15552, 0,
00110 15552, 0);
00111
00112 INIT_FLT_PAR (fp[4], oct_mach_info::flt_fmt_unknown,
00113 0, 0,
00114 0, 0,
00115 0, 0,
00116 0, 0);
00117
00118 equiv mach_fp_par[4];
00119
00120 mach_fp_par[0].d = F77_FUNC (d1mach, D1MACH) (1);
00121 mach_fp_par[1].d = F77_FUNC (d1mach, D1MACH) (2);
00122 mach_fp_par[2].d = F77_FUNC (d1mach, D1MACH) (3);
00123 mach_fp_par[3].d = F77_FUNC (d1mach, D1MACH) (4);
00124
00125 int i = 0;
00126 do
00127 {
00128 if (equiv_compare (fp[i].fp_par, mach_fp_par, 4))
00129 {
00130 retval = fp[i].fp_fmt;
00131 break;
00132 }
00133 }
00134 while (fp[++i].fp_fmt != oct_mach_info::flt_fmt_unknown);
00135
00136 #endif
00137
00138 return retval;
00139 }
00140
00141 static bool
00142 ten_little_endians (void)
00143 {
00144
00145
00146 union
00147 {
00148 long l;
00149 char c[sizeof (long)];
00150 } u;
00151
00152 u.l = 1;
00153
00154 return (u.c[sizeof (long) - 1] == 1);
00155 }
00156
00157 oct_mach_info::oct_mach_info (void)
00158 : native_float_fmt (get_float_format ()),
00159 big_chief (ten_little_endians ()) { }
00160
00161 bool
00162 oct_mach_info::instance_ok (void)
00163 {
00164 bool retval = true;
00165
00166 if (! instance)
00167 {
00168 instance = new oct_mach_info ();
00169
00170 if (instance)
00171 singleton_cleanup_list::add (cleanup_instance);
00172 }
00173
00174 if (! instance)
00175 {
00176 (*current_liboctave_error_handler)
00177 ("unable to create command history object!");
00178
00179 retval = false;
00180 }
00181
00182 return retval;
00183 }
00184
00185 oct_mach_info::float_format
00186 oct_mach_info::native_float_format (void)
00187 {
00188 return (instance_ok ())
00189 ? instance->native_float_fmt : oct_mach_info::flt_fmt_unknown;
00190 }
00191
00192 bool
00193 oct_mach_info::words_big_endian (void)
00194 {
00195 return (instance_ok ())
00196 ? instance->big_chief : false;
00197 }
00198
00199 bool
00200 oct_mach_info::words_little_endian (void)
00201 {
00202 return (instance_ok ())
00203 ? (! instance->big_chief) : false;
00204 }
00205
00206 oct_mach_info::float_format
00207 oct_mach_info::string_to_float_format (const std::string& s)
00208 {
00209 oct_mach_info::float_format retval = oct_mach_info::flt_fmt_unknown;
00210
00211 if (s == "native" || s == "n")
00212 retval = oct_mach_info::native_float_format ();
00213 else if (s == "ieee-be" || s == "b")
00214 retval = oct_mach_info::flt_fmt_ieee_big_endian;
00215 else if (s == "ieee-le" || s == "l")
00216 retval = oct_mach_info::flt_fmt_ieee_little_endian;
00217 else if (s == "vaxd" || s == "d")
00218 retval = oct_mach_info::flt_fmt_vax_d;
00219 else if (s == "vaxg" || s == "g")
00220 retval = oct_mach_info::flt_fmt_vax_g;
00221 else if (s == "cray" || s == "c")
00222 retval = oct_mach_info::flt_fmt_cray;
00223 else if (s == "unknown")
00224 retval = oct_mach_info::flt_fmt_unknown;
00225 else
00226 (*current_liboctave_error_handler)
00227 ("invalid architecture type specified");
00228
00229 return retval;
00230 }
00231
00232 std::string
00233 oct_mach_info::float_format_as_string (float_format flt_fmt)
00234 {
00235 std::string retval = "unknown";
00236
00237 switch (flt_fmt)
00238 {
00239 case flt_fmt_ieee_big_endian:
00240 retval = "ieee_big_endian";
00241 break;
00242
00243 case flt_fmt_ieee_little_endian:
00244 retval = "ieee_little_endian";
00245 break;
00246
00247 case flt_fmt_vax_d:
00248 retval = "vax_d_float";
00249 break;
00250
00251 case flt_fmt_vax_g:
00252 retval = "vax_g_float";
00253 break;
00254
00255 case flt_fmt_cray:
00256 retval = "cray";
00257 break;
00258
00259 default:
00260 break;
00261 }
00262
00263 return retval;
00264 }