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