Fix for assertion error when expanding macro.
[iverilog.git] / vpi / sys_convert.c
blob9c356480812dc8bdad5e441890411244085279c3
1 /*
2 * Copyright (c) 2003 Michael Ruff (mruff at chiaro.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: sys_convert.c,v 1.7 2007/03/14 04:05:51 steve Exp $"
21 #endif
23 # include "vpi_config.h"
24 # include "vpi_user.h"
25 # include <stdio.h>
26 # include <string.h>
27 # include <math.h>
29 static double bits2double(PLI_UINT32 bits[2])
31 union conv {
32 double rval;
33 unsigned char bval[sizeof(double)];
34 } conv;
36 #ifdef WORDS_BIGENDIAN
37 conv.bval[7] = (bits[0] >> 0) & 0xff;
38 conv.bval[6] = (bits[0] >> 8) & 0xff;
39 conv.bval[5] = (bits[0] >> 16) & 0xff;
40 conv.bval[4] = (bits[0] >> 24) & 0xff;
41 conv.bval[3] = (bits[1] >> 0) & 0xff;
42 conv.bval[2] = (bits[1] >> 8) & 0xff;
43 conv.bval[1] = (bits[1] >> 16) & 0xff;
44 conv.bval[0] = (bits[1] >> 24) & 0xff;
45 #else
46 conv.bval[0] = (bits[0] >> 0) & 0xff;
47 conv.bval[1] = (bits[0] >> 8) & 0xff;
48 conv.bval[2] = (bits[0] >> 16) & 0xff;
49 conv.bval[3] = (bits[0] >> 24) & 0xff;
50 conv.bval[4] = (bits[1] >> 0) & 0xff;
51 conv.bval[5] = (bits[1] >> 8) & 0xff;
52 conv.bval[6] = (bits[1] >> 16) & 0xff;
53 conv.bval[7] = (bits[1] >> 24) & 0xff;
54 #endif
56 return conv.rval;
59 static void double2bits(double real, PLI_UINT32 bits[2])
61 union conv {
62 double rval;
63 unsigned char bval[sizeof(double)];
64 } conv;
66 conv.rval = real;
68 #ifdef WORDS_BIGENDIAN
69 bits[0] = conv.bval[7]
70 | (conv.bval[6] << 8)
71 | (conv.bval[5] <<16)
72 | (conv.bval[4] <<24);
73 bits[1] = conv.bval[3]
74 | (conv.bval[2] << 8)
75 | (conv.bval[1] <<16)
76 | (conv.bval[0] <<24);
77 #else
78 bits[0] = conv.bval[0]
79 | (conv.bval[1] << 8)
80 | (conv.bval[2] <<16)
81 | (conv.bval[3] <<24);
82 bits[1] = conv.bval[4]
83 | (conv.bval[5] << 8)
84 | (conv.bval[6] <<16)
85 | (conv.bval[7] <<24);
86 #endif
89 static PLI_INT32 sizetf_32 (PLI_BYTE8*x) { return 32; }
90 static PLI_INT32 sizetf_64 (PLI_BYTE8*x) { return 64; }
92 static PLI_INT32 sys_convert_compiletf(PLI_BYTE8*name)
94 vpiHandle call_hand, argv, arg;
95 PLI_INT32 rtn = 0;
97 call_hand = vpi_handle(vpiSysTfCall, 0);
98 argv = vpi_iterate(vpiArgument, call_hand);
99 arg = vpi_scan(argv);
101 if (!argv) {
102 vpi_printf("ERROR: %s requires a parameter.\n",
103 vpi_get_str(vpiName, call_hand));
104 rtn = -1;
107 if (!strcmp("$bitstoreal", name) && vpi_get(vpiSize, arg) != 64) {
108 vpi_printf("ERROR: %s requires 64-bit argument.\n",
109 vpi_get_str(vpiName, call_hand));
110 rtn = -1;
113 /* free iterator */
114 vpi_free_object(argv);
116 return rtn;
119 static PLI_INT32 sys_bitstoreal_calltf(PLI_BYTE8*user)
121 vpiHandle sys, argv, arg;
122 s_vpi_value value;
124 PLI_UINT32 bits[2];
126 /* find argument handle */
127 sys = vpi_handle(vpiSysTfCall, 0);
128 argv = vpi_iterate(vpiArgument, sys);
129 arg = vpi_scan(argv);
131 /* get value */
132 value.format = vpiVectorVal;
133 vpi_get_value(arg, &value);
135 /* convert */
136 bits[0] = (value.value.vector[0]).aval;
137 bits[1] = (value.value.vector[1]).aval;
138 value.value.real = bits2double(bits);
139 value.format = vpiRealVal;
141 /* return converted value */
142 vpi_put_value(sys, &value, 0, vpiNoDelay);
144 /* free iterator */
145 vpi_free_object(argv);
147 return 0;
150 static PLI_INT32 sys_itor_calltf(PLI_BYTE8*user)
152 vpiHandle sys, argv, arg;
153 s_vpi_value value;
155 /* find argument handle */
156 sys = vpi_handle(vpiSysTfCall, 0);
157 argv = vpi_iterate(vpiArgument, sys);
158 arg = vpi_scan(argv);
160 /* get value */
161 value.format = vpiIntVal;
162 vpi_get_value(arg, &value);
164 /* convert */
165 value.value.real = (PLI_INT32)value.value.integer;
166 value.format = vpiRealVal;
168 /* return converted value */
169 vpi_put_value(sys, &value, 0, vpiNoDelay);
171 /* free iterator */
172 vpi_free_object(argv);
174 return 0;
177 static PLI_INT32 sys_realtobits_calltf(PLI_BYTE8*user)
179 vpiHandle sys, argv, arg;
180 s_vpi_value value;
181 static struct t_vpi_vecval res[2];
183 PLI_UINT32 bits[2];
185 /* find argument handle */
186 sys = vpi_handle(vpiSysTfCall, 0);
187 argv = vpi_iterate(vpiArgument, sys);
188 arg = vpi_scan(argv);
190 /* get value */
191 value.format = vpiRealVal;
192 vpi_get_value(arg, &value);
194 /* convert */
195 double2bits(value.value.real, bits);
197 res[0].aval = bits[0];
198 res[0].bval = 0;
199 res[1].aval = bits[1];
200 res[1].bval = 0;
202 value.format = vpiVectorVal;
203 value.value.vector = res;
205 /* return converted value */
206 vpi_put_value(sys, &value, 0, vpiNoDelay);
208 /* free iterator */
209 vpi_free_object(argv);
211 return 0;
214 static PLI_INT32 sys_rtoi_calltf(PLI_BYTE8*user)
216 vpiHandle sys, argv, arg;
217 s_vpi_value value;
218 static struct t_vpi_vecval res;
220 /* find argument handle */
221 sys = vpi_handle(vpiSysTfCall, 0);
222 argv = vpi_iterate(vpiArgument, sys);
223 arg = vpi_scan(argv);
225 /* get value */
226 value.format = vpiRealVal;
227 vpi_get_value(arg, &value);
229 /* convert */
230 res.aval = (unsigned)value.value.real;
231 res.bval = 0;
233 value.format = vpiVectorVal;
234 value.value.vector = &res;
236 /* return converted value */
237 vpi_put_value(sys, &value, 0, vpiNoDelay);
239 /* free iterator */
240 vpi_free_object(argv);
242 return 0;
245 void sys_convert_register()
247 s_vpi_systf_data tf_data;
249 tf_data.type = vpiSysFunc;
250 tf_data.user_data = "$bitstoreal";
251 tf_data.tfname = tf_data.user_data;
252 tf_data.sizetf = sizetf_64;
253 tf_data.compiletf = sys_convert_compiletf;
254 tf_data.calltf = sys_bitstoreal_calltf;
255 vpi_register_systf(&tf_data);
257 tf_data.type = vpiSysFunc;
258 tf_data.user_data = "$itor";
259 tf_data.tfname = tf_data.user_data;
260 tf_data.sizetf = sizetf_64;
261 tf_data.compiletf = sys_convert_compiletf;
262 tf_data.calltf = sys_itor_calltf;
263 vpi_register_systf(&tf_data);
265 tf_data.type = vpiSysFunc;
266 tf_data.user_data = "$realtobits";
267 tf_data.tfname = tf_data.user_data;
268 tf_data.sizetf = sizetf_64;
269 tf_data.compiletf = sys_convert_compiletf;
270 tf_data.calltf = sys_realtobits_calltf;
271 vpi_register_systf(&tf_data);
273 tf_data.type = vpiSysFunc;
274 tf_data.user_data = "$rtoi";
275 tf_data.tfname = tf_data.user_data;
276 tf_data.sizetf = sizetf_32;
277 tf_data.compiletf = sys_convert_compiletf;
278 tf_data.calltf = sys_rtoi_calltf;
279 vpi_register_systf(&tf_data);
283 * $Log: sys_convert.c,v $
284 * Revision 1.7 2007/03/14 04:05:51 steve
285 * VPI tasks take PLI_BYTE* by the standard.
287 * Revision 1.6 2006/10/30 22:45:37 steve
288 * Updates for Cygwin portability (pr1585922)
290 * Revision 1.5 2004/02/15 18:03:30 steve
291 * Cleanup of warnings.
293 * Revision 1.4 2004/01/21 01:22:53 steve
294 * Give the vip directory its own configure and vpi_config.h
296 * Revision 1.3 2003/03/17 21:59:54 steve
297 * Implement $itor and $bitstoreal
299 * Revision 1.2 2003/03/10 23:40:10 steve
300 * Add support for $rtoi
302 * Revision 1.1 2003/03/07 02:44:34 steve
303 * Implement $realtobits.