1 /*
2 * Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
3 *
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.
9 *
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.
14 *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 # include "config.h"
21
22 # include <iostream>
23
24 # include <cstring>
25 # include "t-dll.h"
26 # include "netlist.h"
27 # include "netclass.h"
28 # include <cassert>
29 # include <cstdlib>
30 # include "ivl_alloc.h"
31 # include "ivl_assert.h"
32
33 /*
34 * This is a little convenience function for converting a NetExpr
35 * expression type to the expression type used by ivl_expr_t objects.
36 */
get_expr_type(const NetExpr * net)37 static ivl_variable_type_t get_expr_type(const NetExpr*net)
38 {
39 return net->expr_type();
40 }
41
42 /*
43 * These methods implement the expression scan that generates the
44 * ivl_expr_t representing the expression. Each method leaves the
45 * expr_ member filled with the ivl_expr_t that represents it. Each
46 * method expects that the expr_ member empty (0) when it starts.
47 */
48
49 /*
50 * This function takes an expression in the expr_ member that is
51 * already built up, and adds a subtraction of the given constant.
52 */
sub_off_from_expr_(long off)53 void dll_target::sub_off_from_expr_(long off)
54 {
55 assert(expr_ != 0);
56
57 char*bits;
58 ivl_expr_t tmpc = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
59 tmpc->type_ = IVL_EX_NUMBER;
60 tmpc->value_ = IVL_VT_VECTOR;
61 tmpc->net_type= 0;
62 tmpc->width_ = expr_->width_;
63 tmpc->signed_ = expr_->signed_;
64 tmpc->sized_ = 1;
65 tmpc->u_.number_.bits_ = bits = (char*)malloc(tmpc->width_);
66 for (unsigned idx = 0 ; idx < tmpc->width_ ; idx += 1) {
67 bits[idx] = (off & 1)? '1' : '0';
68 off >>= 1;
69 }
70
71 /* Now make the subtracter (x-4 in the above example)
72 that has as input A the index expression and input B
73 the constant to subtract. */
74 ivl_expr_t tmps = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
75 tmps->type_ = IVL_EX_BINARY;
76 tmps->value_ = IVL_VT_VECTOR;
77 tmps->net_type= 0;
78 tmps->width_ = tmpc->width_;
79 tmps->signed_ = tmpc->signed_;
80 tmps->sized_ = 1;
81 tmps->u_.binary_.op_ = '-';
82 tmps->u_.binary_.lef_ = expr_;
83 tmps->u_.binary_.rig_ = tmpc;
84
85 /* Replace (x) with (x-off) */
86 expr_ = tmps;
87 }
88
mul_expr_by_const_(long val)89 void dll_target::mul_expr_by_const_(long val)
90 {
91 assert(expr_ != 0);
92
93 char*bits;
94 ivl_expr_t tmpc = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
95 tmpc->type_ = IVL_EX_NUMBER;
96 tmpc->value_ = IVL_VT_VECTOR;
97 tmpc->net_type= 0;
98 tmpc->width_ = expr_->width_;
99 tmpc->signed_ = expr_->signed_;
100 tmpc->sized_ = 1;
101 tmpc->u_.number_.bits_ = bits = (char*)malloc(tmpc->width_);
102 for (unsigned idx = 0 ; idx < tmpc->width_ ; idx += 1) {
103 bits[idx] = (val & 1)? '1' : '0';
104 val >>= 1;
105 }
106
107 /* Now make the subtracter (x-4 in the above example)
108 that has as input A the index expression and input B
109 the constant to subtract. */
110 ivl_expr_t tmps = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
111 tmps->type_ = IVL_EX_BINARY;
112 tmps->value_ = IVL_VT_VECTOR;
113 tmpc->net_type= 0;
114 tmps->width_ = tmpc->width_;
115 tmps->signed_ = tmpc->signed_;
116 tmps->sized_ = 1;
117 tmps->u_.binary_.op_ = '*';
118 tmps->u_.binary_.lef_ = expr_;
119 tmps->u_.binary_.rig_ = tmpc;
120
121 /* Replace (x) with (x*valf) */
122 expr_ = tmps;
123 }
124
expr_from_value_(const verinum & val)125 ivl_expr_t dll_target::expr_from_value_(const verinum&val)
126 {
127 ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
128
129 unsigned idx;
130 char*bits;
131 expr->type_ = IVL_EX_NUMBER;
132 expr->value_= IVL_VT_VECTOR;
133 expr->net_type=0;
134 expr->width_= val.len();
135 expr->signed_ = val.has_sign()? 1 : 0;
136 expr->sized_= 1;
137 expr->u_.number_.bits_ = bits = (char*)malloc(expr->width_ + 1);
138 for (idx = 0 ; idx < expr->width_ ; idx += 1)
139 switch (val.get(idx)) {
140 case verinum::V0:
141 bits[idx] = '0';
142 break;
143 case verinum::V1:
144 bits[idx] = '1';
145 break;
146 case verinum::Vx:
147 bits[idx] = 'x';
148 break;
149 case verinum::Vz:
150 bits[idx] = 'z';
151 break;
152 default:
153 assert(0);
154 }
155
156 bits[expr->width_] = 0;
157
158 return expr;
159 }
160
expr_access_func(const NetEAccess * net)161 void dll_target::expr_access_func(const NetEAccess*net)
162 {
163 assert(expr_ == 0);
164 // Make a stub Branch Access Function expression node.
165 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
166 expr_->type_ = IVL_EX_BACCESS;
167 expr_->value_ = IVL_VT_REAL;
168 expr_->net_type=0;
169 expr_->width_ = 1;
170 expr_->signed_= 1;
171 expr_->sized_ = 1;
172 FILE_NAME(expr_, net);
173
174 expr_->u_.branch_.branch = net->get_branch()->target_obj();
175 expr_->u_.branch_.nature = net->get_nature();
176 }
177
expr_array_pattern(const NetEArrayPattern * net)178 void dll_target::expr_array_pattern(const NetEArrayPattern*net)
179 {
180 assert(expr_ == 0);
181 ivl_expr_t expr_tmp = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
182 expr_tmp->type_ = IVL_EX_ARRAY_PATTERN;
183 expr_tmp->value_= net->expr_type();
184 expr_tmp->net_type = net->net_type();
185 expr_tmp->width_ = 1;
186 expr_tmp->signed_ = 0;
187 expr_tmp->sized_ = 0;
188 FILE_NAME(expr_tmp, net);
189
190 expr_tmp->u_.array_pattern_.parms = net->item_size();
191 expr_tmp->u_.array_pattern_.parm = new ivl_expr_t [net->item_size()];
192
193 for (size_t idx = 0 ; idx < net->item_size() ; idx += 1) {
194 const NetExpr*tmp = net->item(idx);
195 tmp->expr_scan(this);
196 expr_tmp->u_.array_pattern_.parm[idx] = expr_;
197 expr_ = 0;
198 }
199
200 expr_ = expr_tmp;
201 }
202
expr_binary(const NetEBinary * net)203 void dll_target::expr_binary(const NetEBinary*net)
204 {
205 assert(expr_ == 0);
206
207 net->left()->expr_scan(this);
208 ivl_expr_t left = expr_;
209
210 expr_ = 0;
211 net->right()->expr_scan(this);
212 ivl_expr_t rght = expr_;
213
214 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
215
216 expr_->type_ = IVL_EX_BINARY;
217 expr_->value_= get_expr_type(net);
218 expr_->net_type=0;
219 expr_->width_= net->expr_width();
220 expr_->signed_ = net->has_sign()? 1 : 0;
221 expr_->sized_= 1;
222 FILE_NAME(expr_, net);
223
224 expr_->u_.binary_.op_ = net->op();
225 expr_->u_.binary_.lef_ = left;
226 expr_->u_.binary_.rig_ = rght;
227 }
228
expr_concat(const NetEConcat * net)229 void dll_target::expr_concat(const NetEConcat*net)
230 {
231 assert(expr_ == 0);
232
233 ivl_expr_t cur = new struct ivl_expr_s;
234 assert(cur);
235
236 cur->type_ = IVL_EX_CONCAT;
237 cur->value_ = net->expr_type();
238 cur->net_type=0;
239 cur->width_ = net->expr_width();
240 cur->signed_ = net->has_sign() ? 1 : 0;
241 cur->sized_ = 1;
242 FILE_NAME(cur, net);
243
244 cur->u_.concat_.rept = net->repeat();
245 cur->u_.concat_.parms = net->nparms();
246 cur->u_.concat_.parm = new ivl_expr_t [net->nparms()];
247
248 for (unsigned idx = 0 ; idx < net->nparms() ; idx += 1) {
249 expr_ = 0;
250 net->parm(idx)->expr_scan(this);
251 assert(expr_);
252 cur->u_.concat_.parm[idx] = expr_;
253 }
254
255 expr_ = cur;
256 }
257
expr_const(const NetEConst * net)258 void dll_target::expr_const(const NetEConst*net)
259 {
260 assert(expr_ == 0);
261
262 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
263 expr_->value_= net->expr_type();
264 expr_->net_type=0;
265 FILE_NAME(expr_, net);
266
267 if (net->value().is_string()) {
268 expr_->type_ = IVL_EX_STRING;
269 expr_->width_= net->expr_width();
270 expr_->u_.string_.value_ =strdup(net->value().as_string().c_str());
271
272 } else {
273 verinum val = net->value();
274 unsigned idx;
275 char*bits;
276 expr_->type_ = IVL_EX_NUMBER;
277 expr_->width_= net->expr_width();
278 expr_->signed_ = net->has_sign()? 1 : 0;
279 expr_->sized_= net->has_width()? 1 : 0;
280 expr_->u_.number_.bits_ = bits = (char*)malloc(expr_->width_);
281 for (idx = 0 ; idx < expr_->width_ ; idx += 1)
282 switch (val.get(idx)) {
283 case verinum::V0:
284 bits[idx] = '0';
285 break;
286 case verinum::V1:
287 bits[idx] = '1';
288 break;
289 case verinum::Vx:
290 bits[idx] = 'x';
291 break;
292 case verinum::Vz:
293 bits[idx] = 'z';
294 break;
295 default:
296 assert(0);
297 }
298
299 }
300 }
301
expr_param(const NetEConstParam * net)302 void dll_target::expr_param(const NetEConstParam*net)
303 {
304 ivl_scope_t scop = find_scope(des_, net->scope());
305 ivl_parameter_t par = scope_find_param(scop, net->name());
306
307 if (par == 0) {
308 cerr << net->get_fileline() << ": internal error: "
309 << "Parameter " << net->name() << " missing from "
310 << ivl_scope_name(scop) << endl;
311 }
312 assert(par);
313 expr_const(net);
314 expr_->u_.string_.parameter = par;
315 }
316
expr_rparam(const NetECRealParam * net)317 void dll_target::expr_rparam(const NetECRealParam*net)
318 {
319 ivl_scope_t scop = find_scope(des_, net->scope());
320 ivl_parameter_t par = scope_find_param(scop, net->name());
321
322 if (par == 0) {
323 cerr << net->get_fileline() << ": internal error: "
324 << "Parameter " << net->name() << " missing from "
325 << ivl_scope_name(scop) << endl;
326 }
327 assert(par);
328 assert(par->value);
329 expr_ = par->value;
330 }
331
expr_creal(const NetECReal * net)332 void dll_target::expr_creal(const NetECReal*net)
333 {
334 assert(expr_ == 0);
335 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
336 expr_->width_ = net->expr_width();
337 expr_->signed_ = 1;
338 expr_->sized_ = 1;
339 expr_->type_ = IVL_EX_REALNUM;
340 FILE_NAME(expr_, net);
341 expr_->value_= IVL_VT_REAL;
342 expr_->net_type=0;
343 expr_->u_.real_.value = net->value().as_double();
344 }
345
expr_last(const NetELast * net)346 void dll_target::expr_last(const NetELast*net)
347 {
348 assert(expr_ == 0);
349 ivl_expr_t expr = new struct ivl_expr_s;
350 expr->type_ = IVL_EX_SFUNC;
351 expr->value_ = IVL_VT_LOGIC;
352 expr->width_ = 32;
353 expr->signed_ = 1;
354 expr->sized_ = 1;
355 expr->net_type = 0;
356 FILE_NAME(expr, net);
357
358 expr->u_.sfunc_.name_ = "$high";
359
360 ivl_signal_t sig = find_signal(des_, net->sig());
361
362 ivl_expr_t esig = new struct ivl_expr_s;
363 esig->type_ = IVL_EX_SIGNAL;
364 esig->value_ = IVL_VT_DARRAY;
365 esig->net_type= sig->net_type;
366 esig->width_ = 1;
367 esig->signed_ = sig->net_type->get_signed()? 1 : 0;
368 FILE_NAME(esig, net);
369 esig->u_.signal_.word = 0;
370 esig->u_.signal_.sig = sig;
371
372 expr->u_.sfunc_.parms = 1;
373 expr->u_.sfunc_.parm = new ivl_expr_t[1];
374 expr->u_.sfunc_.parm[0] = esig;
375
376 expr_ = expr;
377 }
378
expr_new(const NetENew * net)379 void dll_target::expr_new(const NetENew*net)
380 {
381 ivl_expr_t size = 0;
382 ivl_expr_t init_val = 0;
383
384 if (net->size_expr()) {
385 net->size_expr()->expr_scan(this);
386 size = expr_;
387 expr_ = 0;
388 }
389
390 if (net->init_expr()) {
391 net->init_expr()->expr_scan(this);
392 init_val = expr_;
393 expr_ = 0;
394 }
395
396 assert(expr_ == 0);
397 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
398 expr_->width_ = net->expr_width();
399 expr_->signed_ = 0;
400 expr_->sized_ = 1;
401 expr_->type_ = IVL_EX_NEW;
402 FILE_NAME(expr_, net);
403 expr_->value_ = net->expr_type(); // May be IVL_VT_DARRAY or _CLASS
404 expr_->net_type= net->get_type();
405 expr_->u_.new_.size = size;
406 expr_->u_.new_.init_val = init_val;
407 }
408
expr_null(const NetENull * net)409 void dll_target::expr_null(const NetENull*net)
410 {
411 assert(expr_ == 0);
412 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
413 expr_->width_ = net->expr_width();
414 expr_->signed_ = 0;
415 expr_->sized_ = 1;
416 expr_->type_ = IVL_EX_NULL;
417 FILE_NAME(expr_, net);
418 expr_->value_ = IVL_VT_CLASS;
419 expr_->net_type= 0;
420 }
421
expr_property(const NetEProperty * net)422 void dll_target::expr_property(const NetEProperty*net)
423 {
424 ivl_expr_t index = 0;
425 if (const NetExpr*index_expr = net->get_index()) {
426 index_expr->expr_scan(this);
427 index = expr_;
428 expr_ = 0;
429 }
430 assert(expr_ == 0);
431 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
432 expr_->width_ = net->expr_width();
433 expr_->signed_ = net->has_sign();
434 expr_->sized_ = 1;
435 expr_->type_ = IVL_EX_PROPERTY;
436 FILE_NAME(expr_, net);
437 expr_->value_ = net->expr_type();
438 expr_->net_type= net->net_type();
439 expr_->u_.property_.sig = find_signal(des_, net->get_sig());
440 expr_->u_.property_.prop_idx = net->property_idx();
441 expr_->u_.property_.index = index;
442 }
443
expr_event(const NetEEvent * net)444 void dll_target::expr_event(const NetEEvent*net)
445 {
446 assert(expr_ == 0);
447
448 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
449
450 expr_->type_ = IVL_EX_EVENT;
451 FILE_NAME(expr_, net);
452 expr_->value_= IVL_VT_VOID;
453 expr_->net_type=0;
454
455 /* Locate the event by name. Save the ivl_event_t in the
456 expression so that the generator can find it easily. */
457 const NetEvent*ev = net->event();
458 ivl_scope_t ev_scope = lookup_scope_(ev->scope());
459
460 for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) {
461 const char*ename = ivl_event_basename(ev_scope->event_[idx]);
462 if (strcmp(ev->name(), ename) == 0) {
463 expr_->u_.event_.event = ev_scope->event_[idx];
464 break;
465 }
466 }
467 }
468
expr_scope(const NetEScope * net)469 void dll_target::expr_scope(const NetEScope*net)
470 {
471 assert(expr_ == 0);
472
473 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
474
475 expr_->type_ = IVL_EX_SCOPE;
476 FILE_NAME(expr_, net);
477 expr_->value_= IVL_VT_VOID;
478 expr_->net_type=0;
479 expr_->u_.scope_.scope = lookup_scope_(net->scope());
480 }
481
expr_scopy(const NetEShallowCopy * net)482 void dll_target::expr_scopy(const NetEShallowCopy*net)
483 {
484 assert(expr_ == 0);
485
486 net->expr_scan_oper1(this);
487 ivl_expr_t expr1 = expr_;
488 expr_ = 0;
489
490 net->expr_scan_oper2(this);
491 ivl_expr_t expr2 = expr_;
492 expr_ = 0;
493
494 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
495 expr_->type_ = IVL_EX_SHALLOWCOPY;
496 FILE_NAME(expr_, net);
497 expr_->value_ = net->expr_type();
498 expr_->net_type = net->net_type();
499
500 expr_->u_.shallow_.dest = expr1;
501 expr_->u_.shallow_.src = expr2;
502 }
503
expr_netenum(const NetENetenum * net)504 void dll_target::expr_netenum(const NetENetenum*net)
505 {
506 assert(expr_ == 0);
507
508 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
509
510 expr_->type_ = IVL_EX_ENUMTYPE;
511 FILE_NAME(expr_, net);
512 expr_->value_= IVL_VT_VOID;
513 expr_->net_type=0;
514 expr_->u_.enumtype_.type = net->netenum();
515 }
516
expr_select(const NetESelect * net)517 void dll_target::expr_select(const NetESelect*net)
518 {
519 assert(expr_ == 0);
520
521 net->sub_expr()->expr_scan(this);
522 ivl_expr_t expr = expr_;
523
524 expr_ = 0;
525 if (net->select())
526 net->select()->expr_scan(this);
527
528 ivl_expr_t base = expr_;
529
530 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
531
532 expr_->type_ = IVL_EX_SELECT;
533 expr_->value_= net->expr_type();
534 expr_->net_type=0;
535 expr_->width_= net->expr_width();
536 expr_->signed_ = net->has_sign()? 1 : 0;
537 expr_->sized_= 1;
538 FILE_NAME(expr_, net);
539
540 expr_->u_.select_.sel_type_ = net->select_type();
541 expr_->u_.select_.expr_ = expr;
542 expr_->u_.select_.base_ = base;
543 }
544
expr_sfunc(const NetESFunc * net)545 void dll_target::expr_sfunc(const NetESFunc*net)
546 {
547 assert(expr_ == 0);
548
549 ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
550
551 expr->type_ = IVL_EX_SFUNC;
552 expr->value_= net->expr_type();
553 expr->net_type=net->net_type();
554 expr->width_= net->expr_width();
555 expr->signed_ = net->has_sign()? 1 : 0;
556 expr->sized_= 1;
557 FILE_NAME(expr, net);
558 /* system function names are lex_strings strings. */
559 expr->u_.sfunc_.name_ = net->name();
560
561 unsigned cnt = net->nparms();
562 expr->u_.sfunc_.parms = cnt;
563 expr->u_.sfunc_.parm = new ivl_expr_t[cnt];
564
565 /* make up the parameter expressions. */
566 for (unsigned idx = 0 ; idx < cnt ; idx += 1) {
567 net->parm(idx)->expr_scan(this);
568 assert(expr_);
569 expr->u_.sfunc_.parm[idx] = expr_;
570 expr_ = 0;
571 }
572
573 expr_ = expr;
574 }
575
expr_ternary(const NetETernary * net)576 void dll_target::expr_ternary(const NetETernary*net)
577 {
578 assert(expr_ == 0);
579
580 ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
581
582 expr->type_ = IVL_EX_TERNARY;
583 expr->value_= net->expr_type();
584 expr->net_type=0;
585 expr->width_ = net->expr_width();
586 expr->signed_ = net->has_sign()? 1 : 0;
587 expr->sized_ = 1;
588 FILE_NAME(expr, net);
589
590 net->cond_expr()->expr_scan(this);
591 assert(expr_);
592 expr->u_.ternary_.cond = expr_;
593 expr_ = 0;
594
595 net->true_expr()->expr_scan(this);
596 assert(expr_);
597 expr->u_.ternary_.true_e = expr_;
598 expr_ = 0;
599
600 net->false_expr()->expr_scan(this);
601 assert(expr_);
602 expr->u_.ternary_.false_e = expr_;
603
604 expr_ = expr;
605 }
606
expr_signal(const NetESignal * net)607 void dll_target::expr_signal(const NetESignal*net)
608 {
609 ivl_signal_t sig = find_signal(des_, net->sig());
610
611 assert(expr_ == 0);
612
613 /* If there is a word expression, generate it. */
614 ivl_expr_t word_expr = 0;
615 if (const NetExpr*word = net->word_index()) {
616 word->expr_scan(this);
617 assert(expr_);
618 word_expr = expr_;
619 expr_ = 0;
620 }
621
622 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
623
624 expr_->type_ = IVL_EX_SIGNAL;
625 expr_->value_= net->expr_type();
626 expr_->net_type=0;
627 expr_->width_= net->expr_width();
628 expr_->signed_ = net->has_sign()? 1 : 0;
629 expr_->sized_= 1;
630 FILE_NAME(expr_, net);
631 expr_->u_.signal_.word = word_expr;
632 expr_->u_.signal_.sig = sig;
633
634 /* Make account for the special case that this is a reference
635 to an array as a whole. We detect this case by noting that
636 this is an array (more than 0 array dimensions) and that
637 there is no word select expression. For this case, we have
638 an IVL_EX_ARRAY expression instead of a SIGNAL expression. */
639 if (sig->array_dimensions_ > 0 && word_expr == 0) {
640 expr_->type_ = IVL_EX_ARRAY;
641 expr_->width_ = 0; // Doesn't make much sense for arrays.
642 }
643 }
644
645
expr_ufunc(const NetEUFunc * net)646 void dll_target::expr_ufunc(const NetEUFunc*net)
647 {
648 assert(expr_ == 0);
649
650 ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
651
652 expr->type_ = IVL_EX_UFUNC;
653 expr->value_= net->expr_type();
654 expr->net_type=0;
655 expr->width_= net->expr_width();
656 expr->signed_ = net->has_sign()? 1 : 0;
657 expr->sized_= 1;
658 FILE_NAME(expr, net);
659
660 expr->u_.ufunc_.def = lookup_scope_(net->func());
661 if (expr->u_.ufunc_.def == 0) {
662 cerr << net->get_fileline() << ": internal error: "
663 << "dll_target::expr_ufunc: "
664 << "Unable to match scope " << scope_path(net->func()) << endl;
665 }
666 ivl_assert(*net, expr->u_.ufunc_.def);
667 ivl_assert(*net, expr->u_.ufunc_.def->type_ == IVL_SCT_FUNCTION);
668
669 unsigned cnt = net->parm_count();
670 expr->u_.ufunc_.parms = cnt;
671 expr->u_.ufunc_.parm = new ivl_expr_t[cnt];
672
673 /* make up the parameter expressions. */
674 for (unsigned idx = 0 ; idx < cnt ; idx += 1) {
675 net->parm(idx)->expr_scan(this);
676 assert(expr_);
677 expr->u_.ufunc_.parm[idx] = expr_;
678 expr_ = 0;
679 }
680
681 expr_ = expr;
682 }
683
expr_unary(const NetEUnary * net)684 void dll_target::expr_unary(const NetEUnary*net)
685 {
686 assert(expr_ == 0);
687
688 net->expr()->expr_scan(this);
689 assert(expr_);
690
691 ivl_expr_t sub = expr_;
692
693 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
694 expr_->type_ = IVL_EX_UNARY;
695 expr_->value_= net->expr_type();
696 expr_->net_type=0;
697 expr_->width_ = net->expr_width();
698 expr_->signed_ = net->has_sign()? 1 : 0;
699 expr_->sized_ = 1;
700 FILE_NAME(expr_, net);
701 expr_->u_.unary_.op_ = net->op();
702 expr_->u_.unary_.sub_ = sub;
703 }
704