OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [ENODE.cpp] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// CC64 - 'C' derived language compiler
9
//  - 64 bit CPU
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26
#include "stdafx.h"
27
 
28
void swap_nodes(ENODE *node)
29
{
30
        ENODE *temp;
31
        temp = node->p[0];
32
        node->p[0] = node->p[1];
33
        node->p[1] = temp;
34
}
35
 
36
bool ENODE::IsEqualOperand(Operand *a, Operand *b)
37
{
38
        return (Operand::IsEqual(a, b));
39
};
40
 
41
char ENODE::fsize()
42
{
43
        switch (etype) {
44
        case bt_float:  return ('d');
45
        case bt_double: return ('d');
46
        case bt_triple: return ('t');
47
        case bt_quad:   return ('q');
48
        default:        return ('d');
49
        }
50
}
51
 
52
long ENODE::GetReferenceSize()
53
{
54
        switch (nodetype)        /* get load size */
55
        {
56
        case en_b_ref:
57
        case en_ub_ref:
58
        case en_bfieldref:
59
        case en_ubfieldref:
60
                return (1);
61
        case en_c_ref:
62
        case en_uc_ref:
63
        case en_cfieldref:
64
        case en_ucfieldref:
65
                return (2);
66
        case en_ref32:
67
        case en_ref32u:
68
                return (4);
69
        case en_h_ref:
70
        case en_uh_ref:
71
        case en_hfieldref:
72
        case en_uhfieldref:
73
                return (sizeOfWord / 2);
74
        case en_w_ref:
75
        case en_uw_ref:
76
        case en_wfieldref:
77
        case en_uwfieldref:
78
                return (sizeOfWord);
79
        case en_fpregvar:
80
                if (tp)
81
                        return(tp->size);
82
                else
83
                        return (sizeOfFPD);
84
        case en_tempref:
85
        case en_regvar:
86
                return (sizeOfWord);
87
        case en_dbl_ref:
88
                return (sizeOfFPD);
89
        case en_quad_ref:
90
                return (sizeOfFPQ);
91
        case en_flt_ref:
92
                return (sizeOfFPD);
93
        case en_triple_ref:
94
                return (sizeOfFPT);
95
        case en_hp_ref:
96
                return (sizeOfPtr >> 1);
97
        case en_wp_ref:
98
                return (sizeOfPtr);
99
        case en_vector_ref:
100
                return (512);
101
                //                      return node->esize;
102
        }
103
        return (8);
104
}
105
 
106
bool ENODE::IsBitfield()
107
{
108
        return (nodetype == en_wfieldref
109
                || nodetype == en_bfieldref
110
                || nodetype == en_cfieldref
111
                || nodetype == en_hfieldref
112
                || nodetype == en_ubfieldref
113
                || nodetype == en_ucfieldref
114
                || nodetype == en_uhfieldref
115
                || nodetype == en_uwfieldref
116
                );
117
}
118
 
119
//
120
// equalnode will return 1 if the expressions pointed to by
121
// node1 and node2 are equivalent.
122
//
123
bool ENODE::IsEqual(ENODE *node1, ENODE *node2)
124
{
125
        if (node1 == nullptr || node2 == nullptr) {
126
                return (false);
127
        }
128
        if (node1->nodetype != node2->nodetype) {
129
                return (false);
130
        }
131
        switch (node1->nodetype) {
132
        case en_fcon:
133
                return (Float128::IsEqual(&node1->f128, &node2->f128));
134
                //                      return (node1->f == node2->f);
135
        case en_regvar:
136
        case en_fpregvar:
137
        case en_tempref:
138
        case en_icon:
139
        case en_labcon:
140
        case en_classcon:       // Check type ?
141
        case en_autocon:
142
        case en_autovcon:
143
        case en_autofcon:
144
        {
145
                return (node1->i == node2->i);
146
        }
147
        case en_nacon: {
148
                return (node1->sp->compare(*node2->sp) == 0);
149
        }
150
        case en_cnacon:
151
                return (node1->sp->compare(*node2->sp) == 0);
152
        default:
153
                if (IsLValue(node1) && IsEqual(node1->p[0], node2->p[0])) {
154
                        //              if( equalnode(node1->p[0], node2->p[0])  )
155
                        return (true);
156
                }
157
        }
158
        return (false);
159
}
160
 
161
 
162
ENODE *ENODE::Clone()
163
{
164
        ENODE *temp;
165
 
166
        if (this == nullptr)
167
                return (ENODE *)nullptr;
168
        temp = allocEnode();
169
        memcpy(temp, this, sizeof(ENODE));      // copy all the fields
170
        return (temp);
171
}
172
 
173
 
174
 
175
//      repexpr will replace all allocated references within an expression
176
//      with tempref nodes.
177
 
178
void ENODE::repexpr()
179
{
180
        CSE *csp;
181
        if (this == nullptr)
182
                return;
183
        switch (nodetype) {
184
        case en_fcon:
185
        case en_autofcon:
186
        case en_tempfpref:
187
                if ((csp = currentFn->csetbl->Search(this)) != nullptr) {
188
                        csp->isfp = TRUE; //**** a kludge
189
                        if (csp->reg > 0) {
190
                                nodetype = en_fpregvar;
191
                                i = csp->reg;
192
                        }
193
                }
194
                break;
195
                /*
196
                if( (csp = SearchCSEList(node)) != NULL ) {
197
                if( csp->reg > 0 ) {
198
                node->nodetype = en_fpregvar;
199
                node->i = csp->reg;
200
                }
201
                }
202
                break;
203
                */
204
        case en_icon:
205
        case en_nacon:
206
        case en_labcon:
207
        case en_autovcon:
208
        case en_autocon:
209
        case en_classcon:
210
        case en_cnacon:
211
        case en_clabcon:
212
        case en_tempref:
213
                if ((csp = currentFn->csetbl->Search(this)) != NULL) {
214
                        if (csp->reg > 0) {
215
                                nodetype = en_regvar;
216
                                i = csp->reg;
217
                        }
218
                }
219
                break;
220
        case en_ref32: case en_ref32u:
221
        case en_b_ref:
222
        case en_c_ref:
223
        case en_h_ref:
224
        case en_w_ref:
225
        case en_ub_ref:
226
        case en_uc_ref:
227
        case en_uh_ref:
228
        case en_uw_ref:
229
        case en_wp_ref:
230
        case en_hp_ref:
231
        case en_bfieldref:
232
        case en_ubfieldref:
233
        case en_cfieldref:
234
        case en_ucfieldref:
235
        case en_hfieldref:
236
        case en_uhfieldref:
237
        case en_wfieldref:
238
        case en_uwfieldref:
239
        case en_vector_ref:
240
                if ((csp = currentFn->csetbl->Search(this)) != NULL) {
241
                        if (csp->reg > 0) {
242
                                nodetype = en_regvar;
243
                                i = csp->reg;
244
                        }
245
                        else
246
                                p[0]->repexpr();
247
                }
248
                else
249
                        p[0]->repexpr();
250
                break;
251
        case en_dbl_ref:
252
        case en_flt_ref:
253
        case en_quad_ref:
254
                if ((csp = currentFn->csetbl->Search(this)) != NULL) {
255
                        if (csp->reg > 0) {
256
                                nodetype = en_fpregvar;
257
                                i = csp->reg;
258
                        }
259
                        else
260
                                p[0]->repexpr();
261
                }
262
                else
263
                        p[0]->repexpr();
264
                break;
265
        case en_cbc: case en_cubw:
266
        case en_cbh: case en_cucw:
267
        case en_cbw: case en_cuhw:
268
        case en_cbu: case en_ccu: case en_chu:
269
        case en_cubu: case en_cucu: case en_cuhu:
270
        case en_ccwp: case en_cucwp:
271
        case en_cch:
272
        case en_ccw:
273
        case en_chw:
274
        case en_uminus:
275
        case en_abs:
276
        case en_sxb: case en_sxh: case en_sxc:
277
        case en_not:    case en_compl:
278
        case en_chk:
279
                p[0]->repexpr();
280
                break;
281
        case en_i2d:
282
                p[0]->repexpr();
283
                break;
284
        case en_i2q:
285
        case en_d2i:
286
        case en_q2i:
287
        case en_s2q:
288
        case en_d2q:
289
        case en_t2q:
290
                p[0]->repexpr();
291
                break;
292
        case en_add:    case en_sub:
293
        case en_mul:    case en_mulu:   case en_div:    case en_udiv:
294
        case en_mod:    case en_umod:
295
        case en_shl:    case en_asl:
296
        case en_shlu:   case en_shru:   case en_asr:
297
        case en_shr:
298
        case en_and:
299
        case en_or:     case en_xor:
300
        case en_land:   case en_lor:
301
        case en_eq:     case en_ne:
302
        case en_lt:     case en_le:
303
        case en_gt:     case en_ge:
304
        case en_ult:    case en_ule:
305
        case en_ugt:    case en_uge:
306
 
307
        case en_feq:    case en_fne:
308
        case en_flt:    case en_fle:
309
        case en_fgt:    case en_fge:
310
        case en_fdmul:  case en_fddiv:
311
        case en_fdadd:  case en_fdsub:
312
        case en_fadd: case en_fsub:
313
        case en_fmul: case en_fdiv:
314
 
315
        case en_veq:    case en_vne:
316
        case en_vlt:    case en_vle:
317
        case en_vgt:    case en_vge:
318
        case en_vadd: case en_vsub:
319
        case en_vmul: case en_vdiv:
320
        case en_vadds: case en_vsubs:
321
        case en_vmuls: case en_vdivs:
322
 
323
        case en_cond:   case en_void:
324
        case en_asadd:  case en_assub:
325
        case en_asmul:  case en_asmulu:
326
        case en_asdiv:  case en_asdivu:
327
        case en_asor:   case en_asand:    case en_asxor:
328
        case en_asmod:  case en_aslsh:
329
        case en_asrsh:  case en_fcall:
330
        case en_list: case en_aggregate:
331
        case en_assign:
332
                p[0]->repexpr();
333
                p[1]->repexpr();
334
                break;
335
        case en_regvar:
336
        case en_fpregvar:
337
                break;
338
        case en_bchk:
339
                p[0]->repexpr();
340
                p[1]->repexpr();
341
                p[2]->repexpr();
342
                break;
343
        default:
344
                dfs.printf("Uncoded node in repexr():%d\r\n", nodetype);
345
        }
346
}
347
 
348
 
349
/*
350
*      scanexpr will scan the expression pointed to by node for optimizable
351
*      subexpressions. when an optimizable expression is found it is entered
352
*      into the tree. if a reference to an autocon node is scanned the
353
*      corresponding auto dereferenced node will be voided. duse should be
354
*      set if the expression will be dereferenced.
355
*/
356
void ENODE::scanexpr(int duse)
357
{
358
        CSE *csp, *csp1;
359
        int first;
360
        int nn;
361
 
362
        if (this == nullptr)
363
                return;
364
 
365
        switch (nodetype) {
366
        case en_fpregvar:
367
        case en_regvar:
368
                break;
369
        case en_cnacon:
370
        case en_clabcon:
371
        case en_fcon:
372
        case en_icon:
373
        case en_labcon:
374
        case en_nacon:
375
                currentFn->csetbl->InsertNode(this, duse);
376
                break;
377
        case en_autofcon:
378
        case en_tempfpref:
379
                csp1 = currentFn->csetbl->InsertNode(this, duse);
380
                csp1->isfp = TRUE;
381
                if ((nn = currentFn->csetbl->voidauto2(this)) > 0) {
382
                        csp1->duses += loop_active;
383
                        csp1->uses = csp1->duses + nn - loop_active;
384
                }
385
                break;
386
        case en_autovcon:
387
        case en_autocon:
388
        case en_classcon:
389
        case en_tempref:
390
                csp1 = currentFn->csetbl->InsertNode(this, duse);
391
                if ((nn = currentFn->csetbl->voidauto2(this)) > 0) {
392
                        csp1->duses += loop_active;
393
                        csp1->uses = csp1->duses + nn - loop_active;
394
                }
395
                break;
396
        case en_ref32: case en_ref32u:
397
        case en_b_ref:
398
        case en_c_ref:
399
        case en_h_ref:
400
        case en_w_ref:
401
        case en_ub_ref:
402
        case en_uc_ref:
403
        case en_uh_ref:
404
        case en_uw_ref:
405
        case en_flt_ref:
406
        case en_dbl_ref:
407
        case en_quad_ref:
408
        case en_bfieldref:
409
        case en_ubfieldref:
410
        case en_cfieldref:
411
        case en_ucfieldref:
412
        case en_hfieldref:
413
        case en_uhfieldref:
414
        case en_wfieldref:
415
        case en_uwfieldref:
416
        case en_wp_ref:
417
        case en_hp_ref:
418
        case en_vector_ref:
419
                // There is something wrong with the following code that causes
420
                // it to remove zero extension conversion from a byte to a word.
421
                if (p[0]->nodetype == en_autocon || p[0]->nodetype == en_autofcon
422
                        || p[0]->nodetype == en_classcon || p[0]->nodetype == en_autovcon) {
423
                        first = (currentFn->csetbl->Search(this) == nullptr);   // Detect if this is the first insert
424
                        csp = currentFn->csetbl->InsertNode(this, duse);
425
                        if (csp->voidf)
426
                                p[0]->scanexpr(1);
427
                        // take care: the non-derereferenced use of the autocon node may
428
                        // already be in the list. In this case, set voidf to 1
429
                        if (currentFn->csetbl->Search(p[0]) != NULL) {
430
                                csp->voidf = 1;
431
                                p[0]->scanexpr(1);
432
                        }
433
                        else {
434
                                //                        if( csp->voidf )
435
                                //                             scanexpr(node->p[0],1);
436
                                if (first) {
437
                                        ///* look for register nodes */
438
                                        //int i = 0;
439
                                        //long j = node->p[0]->i;
440
                                        //if ((node->p[0]->nodetype== en_regvar || node->p[0]->nodetype==en_bregvar) &&
441
                                        //      (j >= 11 && j < 18))
442
                                        //{
443
                                        //      csp->voidf--;   /* this is not in auto_lst */
444
                                        //      //csp->uses += 90 * (100 - i);
445
                                        //      //csp->duses += 30 * (100 - i);
446
                                        //      break;
447
                                        //}
448
                                        ///* set voidf if the node is not in autolst */
449
                                        //csp->voidf++;
450
                                        //i = 0;
451
                                        //while (i < autoptr) {
452
                                        //      if (autolst[i] == j) {
453
                                        //              csp->voidf--;
454
                                        //              break;
455
                                        //      }
456
                                        //      ++i;
457
                                        //}
458
                                        /*
459
                                        * even if that item must not be put in a register,
460
                                        * it is legal to put its address therein
461
                                        */
462
                                        //if (csp->voidf)
463
                                        //      scanexpr(node->p[0], 1);
464
                                        //}
465
 
466
                                        //if( csp->voidf )
467
                                        //    scanexpr(node->p[0],1);
468
                                }
469
                        }
470
                }
471
                else
472
                        p[0]->scanexpr(1);
473
                break;
474
        case en_cbc: case en_cubw:
475
        case en_cbh: case en_cucw:
476
        case en_cbw: case en_cuhw:
477
        case en_cbu: case en_ccu: case en_chu:
478
        case en_cubu: case en_cucu: case en_cuhu:
479
        case en_ccwp: case en_cucwp:
480
        case en_cch:
481
        case en_ccw:
482
        case en_chw:
483
        case en_uminus:
484
        case en_abs:
485
        case en_sxb: case en_sxc: case en_sxh:
486
        case en_zxb: case en_zxc: case en_zxh:
487
        case en_compl:
488
        case en_not:
489
        case en_chk:
490
                p[0]->scanexpr(duse);
491
                break;
492
        case en_i2d:
493
                p[0]->scanexpr(duse);
494
                break;
495
        case en_i2q:
496
        case en_d2i:
497
        case en_q2i:
498
        case en_s2q:
499
        case en_d2q:
500
        case en_t2q:
501
                p[0]->scanexpr(duse);
502
                break;
503
        case en_asadd:  case en_assub:
504
        case en_add:    case en_sub:
505
                p[0]->scanexpr(duse);
506
                p[1]->scanexpr(duse);
507
                break;
508
        case en_mul:    case en_mulu:   case en_div:    case en_udiv:
509
        case en_shl:    case en_asl:    case en_shlu:   case en_shr:    case en_shru:   case en_asr:
510
        case en_mod:    case en_umod:   case en_and:
511
        case en_or:     case en_xor:
512
        case en_lor:    case en_land:
513
        case en_eq:     case en_ne:
514
        case en_gt:     case en_ge:
515
        case en_lt:     case en_le:
516
        case en_ugt:    case en_uge:
517
        case en_ult:    case en_ule:
518
        case en_feq:    case en_fne:
519
        case en_flt:    case en_fle:
520
        case en_fgt:    case en_fge:
521
        case en_fdmul:  case en_fddiv:
522
        case en_fdadd:  case en_fdsub:
523
        case en_fadd: case en_fsub:
524
        case en_fmul: case en_fdiv:
525
 
526
        case en_veq:    case en_vne:
527
        case en_vlt:    case en_vle:
528
        case en_vgt:    case en_vge:
529
        case en_vadd: case en_vsub:
530
        case en_vmul: case en_vdiv:
531
        case en_vadds: case en_vsubs:
532
        case en_vmuls: case en_vdivs:
533
 
534
        case en_asmul:  case en_asmulu:
535
        case en_asdiv:  case en_asdivu:
536
        case en_asmod:  case en_aslsh:
537
        case en_asrsh:
538
        case en_asand:  case en_asxor: case en_asor:
539
        case en_cond:
540
        case en_void:
541
        case en_list:
542
        case en_aggregate:
543
                p[0]->scanexpr(0);
544
                p[1]->scanexpr(0);
545
                break;
546
        case en_assign:
547
                p[0]->scanexpr(0);
548
                p[1]->scanexpr(0);
549
                break;
550
        case en_fcall:
551
                p[0]->scanexpr(1);
552
                p[1]->scanexpr(0);
553
                break;
554
        case en_bchk:
555
                p[0]->scanexpr(0);
556
                p[1]->scanexpr(0);
557
                p[2]->scanexpr(0);
558
                break;
559
        default: dfs.printf("Uncoded node in ENODE::scanexpr():%d\r\n", nodetype);
560
        }
561
}
562
 
563
 
564
// ----------------------------------------------------------------------------
565
// Generate code to evaluate an index node (^+) and return the addressing mode
566
// of the result. This routine takes no flags since it always returns either
567
// am_ind or am_indx.
568
//
569
// No reason to ReleaseTempReg() because the registers used are transported
570
// forward.
571
// ----------------------------------------------------------------------------
572
Operand *ENODE::GenIndex()
573
{
574
        Operand *ap1, *ap2;
575
 
576
        if ((p[0]->nodetype == en_tempref || p[0]->nodetype == en_regvar)
577
                && (p[1]->nodetype == en_tempref || p[1]->nodetype == en_regvar))
578
        {       /* both nodes are registers */
579
                        // Don't need to free ap2 here. It is included in ap1.
580
                GenerateHint(8);
581
                ap1 = GenerateExpression(p[0], F_REG, 8);
582
                ap2 = GenerateExpression(p[1], F_REG, 8);
583
                GenerateHint(9);
584
                ap1->mode = am_indx2;
585
                ap1->sreg = ap2->preg;
586
                ap1->deep2 = ap2->deep2;
587
                ap1->offset = makeinode(en_icon, 0);
588
                ap1->scale = scale;
589
                return (ap1);
590
        }
591
        GenerateHint(8);
592
        ap1 = GenerateExpression(p[0], F_REG | F_IMMED, 8);
593
        if (ap1->mode == am_imm)
594
        {
595
                ap2 = GenerateExpression(p[1], F_REG | F_IMM0, 8);
596
                if (ap2->mode == am_imm) {      // value is zero
597
                        ap1->mode = am_direct;
598
                        return (ap1);
599
                }
600
                GenerateHint(9);
601
                ap2->mode = am_indx;
602
                ap2->offset = ap1->offset;
603
                ap2->isUnsigned = ap1->isUnsigned;
604
                return (ap2);
605
        }
606
        ap2 = GenerateExpression(p[1], F_ALL, 8);   /* get right op */
607
        GenerateHint(9);
608
        if (ap2->mode == am_imm && ap1->mode == am_reg) /* make am_indx */
609
        {
610
                ap2->mode = am_indx;
611
                ap2->preg = ap1->preg;
612
                ap2->deep = ap1->deep;
613
                return ap2;
614
        }
615
        if (ap2->mode == am_ind && ap1->mode == am_reg) {
616
                ap2->mode = am_indx2;
617
                ap2->sreg = ap1->preg;
618
                ap2->deep2 = ap1->deep;
619
                return ap2;
620
        }
621
        if (ap2->mode == am_direct && ap1->mode == am_reg) {
622
                ap2->mode = am_indx;
623
                ap2->preg = ap1->preg;
624
                ap2->deep = ap1->deep;
625
                return ap2;
626
        }
627
        // ap1->mode must be F_REG
628
        ap2->MakeLegal( F_REG, 8);
629
        ap1->mode = am_indx2;            /* make indexed */
630
        ap1->sreg = ap2->preg;
631
        ap1->deep2 = ap2->deep;
632
        ap1->offset = makeinode(en_icon, 0);
633
        ap1->scale = scale;
634
        return ap1;                     /* return indexed */
635
}
636
 
637
 
638
//
639
// Generate code to evaluate a condition operator node (?:)
640
//
641
Operand *ENODE::GenHook(int flags, int size)
642
{
643
        Operand *ap1, *ap2, *ap3, *ap4;
644
        int false_label, end_label;
645
        OCODE *ip1;
646
        int n1;
647
        ENODE *node;
648
 
649
        false_label = nextlabel++;
650
        end_label = nextlabel++;
651
        flags = (flags & F_REG) | F_VOL;
652
        /*
653
        if (p[0]->constflag && p[1]->constflag) {
654
        GeneratePredicateMonadic(hook_predreg,op_op_ldi,make_immed(p[0]->i));
655
        GeneratePredicateMonadic(hook_predreg,op_ldi,make_immed(p[0]->i));
656
        }
657
        */
658
        ip1 = peep_tail;
659
        if (!opt_nocgo) {
660
                ap4 = GetTempRegister();
661
                ap1 = GenerateExpression(p[0], flags, size);
662
                ap2 = GenerateExpression(p[1]->p[0], flags, size);
663
                ap3 = GenerateExpression(p[1]->p[1], (flags & ~F_VOL) | F_IMMED, size);
664
                n1 = PeepCount(ip1);
665
                if (n1 < 20) {
666
                        Generate4adic(op_cmovenz, 0, ap4, ap1, ap2, ap3);
667
                        ReleaseTempReg(ap3);
668
                        ReleaseTempReg(ap2);
669
                        ReleaseTempReg(ap1);
670
                        return (ap4);
671
                }
672
                ReleaseTempReg(ap3);
673
                ReleaseTempReg(ap2);
674
                ReleaseTempReg(ap1);
675
                ReleaseTempReg(ap4);
676
                peep_tail = ip1;
677
                peep_tail->fwd = nullptr;
678
        }
679
        ap2 = GenerateExpression(p[1]->p[1], flags, size);
680
        n1 = PeepCount(ip1);
681
        if (opt_nocgo)
682
                n1 = 9999;
683
        if (n1 > 4) {
684
                peep_tail = ip1;
685
                peep_tail->fwd = nullptr;
686
        }
687
        GenerateFalseJump(p[0], false_label, 0);
688
        node = p[1];
689
        ap1 = GenerateExpression(node->p[0], flags, size);
690
        if (n1 > 4)
691
                GenerateDiadic(op_bra, 0, make_clabel(end_label), 0);
692
        else {
693
                if (!IsEqualOperand(ap1, ap2))
694
                {
695
                        GenerateMonadic(op_hint, 0, make_immed(2));
696
                        GenerateDiadic(op_mov, 0, ap2, ap1);
697
                }
698
        }
699
        GenerateLabel(false_label);
700
        if (n1 > 4) {
701
                ap2 = GenerateExpression(node->p[1], flags, size);
702
                if (!IsEqualOperand(ap1, ap2))
703
                {
704
                        GenerateMonadic(op_hint, 0, make_immed(2));
705
                        GenerateDiadic(op_mov, 0, ap1, ap2);
706
                }
707
        }
708
        if (n1 > 4) {
709
                ReleaseTempReg(ap2);
710
                GenerateLabel(end_label);
711
                return (ap1);
712
        }
713
        else {
714
                ReleaseTempReg(ap1);
715
                GenerateLabel(end_label);
716
                return (ap2);
717
        }
718
}
719
 
720
Operand *ENODE::GenShift(int flags, int size, int op)
721
{
722
        Operand *ap1, *ap2, *ap3;
723
 
724
        ap3 = GetTempRegister();
725
        ap1 = GenerateExpression(p[0], F_REG, size);
726
        ap2 = GenerateExpression(p[1], F_REG | F_IMM6, 8);
727
        GenerateTriadic(op, size, ap3, ap1, ap2);
728
        // Rotates automatically sign extend
729
        if ((op == op_rol || op == op_ror) && ap2->isUnsigned)
730
                switch (size) {
731
                case 1: GenerateDiadic(op_zxb, 0, ap3, ap3); break;
732
                case 2: GenerateDiadic(op_zxc, 0, ap3, ap3); break;
733
                case 4: GenerateDiadic(op_zxh, 0, ap3, ap3); break;
734
                default:;
735
                }
736
        ReleaseTempRegister(ap2);
737
        ReleaseTempRegister(ap1);
738
        ap3->MakeLegal(flags, size);
739
        return (ap3);
740
}
741
 
742
 
743
Operand *ENODE::GenAssignShift(int flags, int size, int op)
744
{
745
        Operand    *ap1, *ap2, *ap3;
746
 
747
        //size = GetNaturalSize(node->p[0]);
748
        ap3 = GenerateExpression(p[0], F_ALL & ~F_IMMED, size);
749
        ap2 = GenerateExpression(p[1], F_REG | F_IMM6, size);
750
        if (ap3->mode == am_reg) {
751
                GenerateTriadic(op, size, ap3, ap3, ap2);
752
                ReleaseTempRegister(ap2);
753
                ap3->MakeLegal(flags, size);
754
                return (ap3);
755
        }
756
        ap1 = GetTempRegister();
757
        GenLoad(ap1, ap3, size, size);
758
        GenerateTriadic(op, size, ap1, ap1, ap2);
759
        GenStore(ap1, ap3, size);
760
        ReleaseTempRegister(ap1);
761
        ReleaseTempRegister(ap2);
762
        ap3->MakeLegal(flags, size);
763
        return (ap3);
764
}
765
 
766
 
767
//
768
//      generate code to evaluate a mod operator or a divide
769
//      operator.
770
//
771
Operand *ENODE::GenDivMod(int flags, int size, int op)
772
{
773
        Operand *ap1, *ap2, *ap3;
774
 
775
        //if( node->p[0]->nodetype == en_icon ) //???
776
        //      swap_nodes(node);
777
        if (op == op_fdiv) {
778
                ap3 = GetTempFPRegister();
779
                ap1 = GenerateExpression(p[0], F_FPREG, 8);
780
                ap2 = GenerateExpression(p[1], F_FPREG, 8);
781
        }
782
        else {
783
                ap3 = GetTempRegister();
784
                ap1 = GenerateExpression(p[0], F_REG, 8);
785
                ap2 = GenerateExpression(p[1], F_REG | F_IMMED, 8);
786
        }
787
        if (op == op_fdiv) {
788
                // Generate a convert operation ?
789
                if (ap1->fpsize() != ap2->fpsize()) {
790
                        if (ap2->fpsize() == 's')
791
                                GenerateDiadic(op_fcvtsq, 0, ap2, ap2);
792
                }
793
                GenerateTriadic(op, ap1->fpsize(), ap3, ap1, ap2);
794
        }
795
        else
796
                GenerateTriadic(op, 0, ap3, ap1, ap2);
797
        //    GenerateDiadic(op_ext,0,ap3,0);
798
        ap3->MakeLegal( flags, 2);
799
        ReleaseTempReg(ap2);
800
        ReleaseTempReg(ap1);
801
        return (ap3);
802
}
803
 
804
 
805
//
806
// Generate code to evaluate a unary minus or complement.
807
//
808
Operand *ENODE::GenUnary(int flags, int size, int op)
809
{
810
        Operand *ap, *ap2;
811
 
812
        if (IsFloatType()) {
813
                ap2 = GetTempFPRegister();
814
                ap = GenerateExpression(p[0], F_FPREG, size);
815
                if (op == op_neg)
816
                        op = op_fneg;
817
                GenerateDiadic(op, fsize(), ap2, ap);
818
        }
819
        else if (etype == bt_vector) {
820
                ap2 = GetTempVectorRegister();
821
                ap = GenerateExpression(p[0], F_VREG, size);
822
                GenerateDiadic(op, 0, ap2, ap);
823
        }
824
        else {
825
                ap2 = GetTempRegister();
826
                ap = GenerateExpression(p[0], F_REG, size);
827
                GenerateHint(3);
828
                GenerateDiadic(op, 0, ap2, ap);
829
        }
830
        ReleaseTempReg(ap);
831
        ap2->MakeLegal( flags, size);
832
        return (ap2);
833
}
834
 
835
// Generate code for a binary expression
836
 
837
Operand *ENODE::GenBinary(int flags, int size, int op)
838
{
839
        Operand *ap1, *ap2, *ap3, *ap4;
840
 
841
        if (IsFloatType())
842
        {
843
                ap3 = GetTempFPRegister();
844
                ap1 = GenerateExpression(p[0], F_FPREG, size);
845
                ap2 = GenerateExpression(p[1], F_FPREG, size);
846
                // Generate a convert operation ?
847
                if (ap1->fpsize() != ap2->fpsize()) {
848
                        if (ap2->fpsize() == 's')
849
                                GenerateDiadic(op_fcvtsq, 0, ap2, ap2);
850
                }
851
                GenerateTriadic(op, ap1->fpsize(), ap3, ap1, ap2);
852
                ap3->type = ap1->type;
853
        }
854
        else if (op == op_vadd || op == op_vsub || op == op_vmul || op == op_vdiv
855
                || op == op_vadds || op == op_vsubs || op == op_vmuls || op == op_vdivs
856
                || op == op_veins) {
857
                ap3 = GetTempVectorRegister();
858
                if (ENODE::IsEqual(p[0], p[1]) && !opt_nocgo) {
859
                        ap1 = GenerateExpression(p[0], F_VREG, size);
860
                        ap2 = GenerateExpression(vmask, F_VMREG, size);
861
                        Generate4adic(op, 0, ap3, ap1, ap1, ap2);
862
                        ReleaseTempReg(ap2);
863
                        ap2 = nullptr;
864
                }
865
                else {
866
                        ap1 = GenerateExpression(p[0], F_VREG, size);
867
                        ap2 = GenerateExpression(p[1], F_VREG, size);
868
                        ap4 = GenerateExpression(vmask, F_VMREG, size);
869
                        Generate4adic(op, 0, ap3, ap1, ap2, ap4);
870
                        ReleaseTempReg(ap4);
871
                }
872
                // Generate a convert operation ?
873
                //if (fpsize(ap1) != fpsize(ap2)) {
874
                //      if (fpsize(ap2)=='s')
875
                //              GenerateDiadic(op_fcvtsq, 0, ap2, ap2);
876
                //}
877
        }
878
        else if (op == op_vex) {
879
                ap3 = GetTempRegister();
880
                ap1 = GenerateExpression(p[0], F_REG, size);
881
                ap2 = GenerateExpression(p[1], F_REG, size);
882
                GenerateTriadic(op, 0, ap3, ap1, ap2);
883
        }
884
        else {
885
                ap3 = GetTempRegister();
886
                if (ENODE::IsEqual(p[0], p[1]) && !opt_nocgo) {
887
                        ap1 = GenerateExpression(p[0], F_REG, size);
888
                        ap2 = nullptr;
889
                        GenerateTriadic(op, 0, ap3, ap1, ap1);
890
                }
891
                else {
892
                        ap1 = GenerateExpression(p[0], F_REG, size);
893
                        ap2 = GenerateExpression(p[1], F_REG | F_IMMED, size);
894
                        if (ap2->mode == am_imm) {
895
                                switch (op) {
896
                                case op_and:
897
                                        GenerateTriadic(op, 0, ap3, ap1, make_immed(ap2->offset->i));
898
                                        /*
899
                                        if (ap2->offset->i & 0xFFFF0000LL)
900
                                        GenerateDiadic(op_andq1,0,ap3,make_immed((ap2->offset->i >> 16) & 0xFFFFLL));
901
                                        if (ap2->offset->i & 0xFFFF00000000LL)
902
                                        GenerateDiadic(op_andq2,0,ap3,make_immed((ap2->offset->i >> 32) & 0xFFFFLL));
903
                                        if (ap2->offset->i & 0xFFFF000000000000LL)
904
                                        GenerateDiadic(op_andq3,0,ap3,make_immed((ap2->offset->i >> 48) & 0xFFFFLL));
905
                                        */
906
                                        break;
907
                                case op_or:
908
                                        GenerateTriadic(op, 0, ap3, ap1, make_immed(ap2->offset->i));
909
                                        /*
910
                                        if (ap2->offset->i & 0xFFFF0000LL)
911
                                        GenerateDiadic(op_orq1,0,ap3,make_immed((ap2->offset->i >> 16) & 0xFFFFLL));
912
                                        if (ap2->offset->i & 0xFFFF00000000LL)
913
                                        GenerateDiadic(op_orq2,0,ap3,make_immed((ap2->offset->i >> 32) & 0xFFFFLL));
914
                                        if (ap2->offset->i & 0xFFFF000000000000LL)
915
                                        GenerateDiadic(op_orq3,0,ap3,make_immed((ap2->offset->i >> 48) & 0xFFFFLL));
916
                                        */
917
                                        break;
918
                                        // Most ops handle a max 16 bit immediate operand. If the operand is over 16 bits
919
                                        // it has to be loaded into a register.
920
                                default:
921
                                        if (ap2->offset->i < -32768LL || ap2->offset->i > 32767LL) {
922
                                                ap4 = GetTempRegister();
923
                                                GenerateTriadic(op_or, 0, ap4, makereg(regZero), make_immed(ap2->offset->i));
924
                                                /*
925
                                                if (ap2->offset->i & 0xFFFF0000LL)
926
                                                GenerateDiadic(op_orq1,0,ap4,make_immed((ap2->offset->i >> 16) & 0xFFFFLL));
927
                                                if (ap2->offset->i & 0xFFFF00000000LL)
928
                                                GenerateDiadic(op_orq2,0,ap4,make_immed((ap2->offset->i >> 32) & 0xFFFFLL));
929
                                                if (ap2->offset->i & 0xFFFF000000000000LL)
930
                                                GenerateDiadic(op_orq3,0,ap4,make_immed((ap2->offset->i >> 48) & 0xFFFFLL));
931
                                                */
932
                                                GenerateTriadic(op, 0, ap3, ap1, ap4);
933
                                                ReleaseTempReg(ap4);
934
                                        }
935
                                        else
936
                                                GenerateTriadic(op, 0, ap3, ap1, ap2);
937
                                }
938
                        }
939
                        else
940
                                GenerateTriadic(op, 0, ap3, ap1, ap2);
941
                }
942
        }
943
        if (ap2)
944
                ReleaseTempReg(ap2);
945
        ReleaseTempReg(ap1);
946
        ap3->MakeLegal( flags, size);
947
        return (ap3);
948
}
949
 
950
 
951
Operand *ENODE::GenAssignAdd(int flags, int size, int op)
952
{
953
        Operand *ap1, *ap2, *ap3;
954
        int ssize;
955
        bool negf = false;
956
 
957
        ssize = GetNaturalSize(p[0]);
958
        if (ssize > size)
959
                size = ssize;
960
        if (p[0]->IsBitfield()) {
961
                ap3 = GetTempRegister();
962
                ap1 = GenerateBitfieldDereference(p[0], F_REG | F_MEM, size);
963
                GenerateDiadic(op_mov, 0, ap3, ap1);
964
                ap2 = GenerateExpression(p[1], F_REG | F_IMMED, size);
965
                GenerateTriadic(op, 0, ap1, ap1, ap2);
966
                GenerateBitfieldInsert(ap3, ap1, ap1->offset->bit_offset, ap1->offset->bit_width);
967
                GenStore(ap3, ap1->next, ssize);
968
                ReleaseTempReg(ap2);
969
                ReleaseTempReg(ap1->next);
970
                ReleaseTempReg(ap1);
971
                ap3->MakeLegal( flags, size);
972
                return (ap3);
973
        }
974
        if (IsFloatType()) {
975
                ap1 = GenerateExpression(p[0], F_FPREG | F_MEM, ssize);
976
                ap2 = GenerateExpression(p[1], F_FPREG, size);
977
                if (op == op_add)
978
                        op = op_fadd;
979
                else if (op == op_sub)
980
                        op = op_fsub;
981
        }
982
        else if (etype == bt_vector) {
983
                ap1 = GenerateExpression(p[0], F_REG | F_MEM, ssize);
984
                ap2 = GenerateExpression(p[1], F_REG, size);
985
                if (op == op_add)
986
                        op = op_vadd;
987
                else if (op == op_sub)
988
                        op = op_vsub;
989
        }
990
        else {
991
                ap1 = GenerateExpression(p[0], F_ALL, ssize);
992
                ap2 = GenerateExpression(p[1], F_REG | F_IMMED, size);
993
        }
994
        if (ap1->mode == am_reg) {
995
                GenerateTriadic(op, 0, ap1, ap1, ap2);
996
        }
997
        else if (ap1->mode == am_fpreg) {
998
                GenerateTriadic(op, ap1->fpsize(), ap1, ap1, ap2);
999
                ReleaseTempReg(ap2);
1000
                ap1->MakeLegal( flags, size);
1001
                return (ap1);
1002
        }
1003
        else {
1004
                GenMemop(op, ap1, ap2, ssize);
1005
        }
1006
        ReleaseTempReg(ap2);
1007
        if (ap1->type != stddouble.GetIndex() && !ap1->isUnsigned)
1008
                ap1->GenSignExtend(ssize, size, flags);
1009
        ap1->MakeLegal( flags, size);
1010
        return (ap1);
1011
}
1012
 
1013
Operand *ENODE::GenAssignLogic(int flags, int size, int op)
1014
{
1015
        Operand *ap1, *ap2, *ap3;
1016
        int ssize;
1017
 
1018
        ssize = GetNaturalSize(p[0]);
1019
        if (ssize > size)
1020
                size = ssize;
1021
        if (p[0]->IsBitfield()) {
1022
                ap3 = GetTempRegister();
1023
                ap1 = GenerateBitfieldDereference(p[0], F_REG | F_MEM, size);
1024
                GenerateDiadic(op_mov, 0, ap3, ap1);
1025
                ap2 = GenerateExpression(p[1], F_REG | F_IMMED, size);
1026
                GenerateTriadic(op, 0, ap1, ap1, ap2);
1027
                GenerateBitfieldInsert(ap3, ap1, ap1->offset->bit_offset, ap1->offset->bit_width);
1028
                GenStore(ap3, ap1->next, ssize);
1029
                ReleaseTempReg(ap2);
1030
                ReleaseTempReg(ap1->next);
1031
                ReleaseTempReg(ap1);
1032
                ap3->MakeLegal( flags, size);
1033
                return (ap3);
1034
        }
1035
        ap1 = GenerateExpression(p[0], F_ALL & ~F_FPREG, ssize);
1036
        ap2 = GenerateExpression(p[1], F_REG | F_IMMED, size);
1037
        if (ap1->mode == am_reg) {
1038
                GenerateTriadic(op, 0, ap1, ap1, ap2);
1039
        }
1040
        else {
1041
                GenMemop(op, ap1, ap2, ssize);
1042
        }
1043
        ReleaseTempRegister(ap2);
1044
        if (!ap1->isUnsigned && !(flags & F_NOVALUE)) {
1045
                if (size > ssize) {
1046
                        if (ap1->mode != am_reg) {
1047
                                ap1->MakeLegal( F_REG, ssize);
1048
                        }
1049
                        switch (ssize) {
1050
                        case 1: GenerateDiadic(op_sxb, 0, ap1, ap1); break;
1051
                        case 2: GenerateDiadic(op_sxc, 0, ap1, ap1); break;
1052
                        case 4: GenerateDiadic(op_sxh, 0, ap1, ap1); break;
1053
                        }
1054
                        ap1->MakeLegal( flags, size);
1055
                        return (ap1);
1056
                }
1057
                ap1->GenSignExtend(ssize, size, flags);
1058
        }
1059
        ap1->MakeLegal( flags, size);
1060
        return (ap1);
1061
}
1062
 
1063
Operand *ENODE::GenLand(int flags, int op)
1064
{
1065
        Operand *ap1, *ap2, *ap3, *ap4, *ap5;
1066
 
1067
        ap3 = GetTempRegister();
1068
        ap1 = GenerateExpression(p[0], flags, 8);
1069
        ap4 = GetTempRegister();
1070
        GenerateDiadic(op_redor, 0, ap4, ap1);
1071
        ap2 = GenerateExpression(p[1], flags, 8);
1072
        ap5 = GetTempRegister();
1073
        GenerateDiadic(op_redor, 0, ap5, ap2);
1074
        GenerateTriadic(op, 0, ap3, ap4, ap5);
1075
        ReleaseTempReg(ap5);
1076
        ReleaseTempReg(ap2);
1077
        ReleaseTempReg(ap4);
1078
        ReleaseTempReg(ap1);
1079
        ap3->MakeLegal( flags, 8);
1080
        return (ap3);
1081
}
1082
 
1083
void ENODE::PutConstant(txtoStream& ofs, unsigned int lowhigh, unsigned int rshift)
1084
{
1085
        // ASM statment text (up to 3500 chars) may be placed in the following buffer.
1086
        static char buf[4000];
1087
 
1088
        switch (nodetype)
1089
        {
1090
        case en_autofcon:
1091
                sprintf_s(buf, sizeof(buf), "%lld", i);
1092
                ofs.write(buf);
1093
                break;
1094
        case en_fcon:
1095
                goto j1;
1096
                // The following spits out a warning, but is okay.
1097
                sprintf_s(buf, sizeof(buf), "0x%llx", f);
1098
                ofs.write(buf);
1099
                break;
1100
        case en_autovcon:
1101
        case en_autocon:
1102
        case en_icon:
1103
                if (lowhigh == 2) {
1104
                        sprintf_s(buf, sizeof(buf), "%lld", i & 0xffff);
1105
                        ofs.write(buf);
1106
                }
1107
                else if (lowhigh == 3) {
1108
                        sprintf_s(buf, sizeof(buf), "%lld", (i >> 16) & 0xffff);
1109
                        ofs.write(buf);
1110
                }
1111
                else {
1112
                        sprintf_s(buf, sizeof(buf), "%lld", i);
1113
                        ofs.write(buf);
1114
                }
1115
                if (rshift > 0) {
1116
                        sprintf_s(buf, sizeof(buf), ">>%d", rshift);
1117
                        ofs.write(buf);
1118
                }
1119
                break;
1120
        case en_labcon:
1121
        j1:
1122
                sprintf_s(buf, sizeof(buf), "%s_%lld", GetNamespace(), i);
1123
                ofs.write(buf);
1124
                if (rshift > 0) {
1125
                        sprintf_s(buf, sizeof(buf), ">>%d", rshift);
1126
                        ofs.write(buf);
1127
                }
1128
                break;
1129
        case en_clabcon:
1130
                sprintf_s(buf, sizeof(buf), "%s_%lld", GetNamespace(), i);
1131
                ofs.write(buf);
1132
                if (rshift > 0) {
1133
                        sprintf_s(buf, sizeof(buf), ">>%d", rshift);
1134
                        ofs.write(buf);
1135
                }
1136
                break;
1137
        case en_nacon:
1138
                sprintf_s(buf, sizeof(buf), "%s", (char *)sp->c_str());
1139
                ofs.write(buf);
1140
                if (lowhigh == 3) {
1141
                        sprintf_s(buf, sizeof(buf), ">>16");
1142
                        ofs.write(buf);
1143
                }
1144
                if (rshift > 0) {
1145
                        sprintf_s(buf, sizeof(buf), ">>%d", rshift);
1146
                        ofs.write(buf);
1147
                }
1148
                break;
1149
        case en_cnacon:
1150
                sprintf_s(buf, sizeof(buf), "%s", (char *)msp->c_str());
1151
                ofs.write(buf);
1152
                if (rshift > 0) {
1153
                        sprintf_s(buf, sizeof(buf), ">>%d", rshift);
1154
                        ofs.write(buf);
1155
                }
1156
                break;
1157
        case en_add:
1158
                p[0]->PutConstant(ofs, 0, 0);
1159
                ofs.write("+");
1160
                p[1]->PutConstant(ofs, 0, 0);
1161
                break;
1162
        case en_sub:
1163
                p[0]->PutConstant(ofs, 0, 0);
1164
                ofs.write("-");
1165
                p[1]->PutConstant(ofs, 0, 0);
1166
                break;
1167
        case en_uminus:
1168
                ofs.write("-");
1169
                p[0]->PutConstant(ofs, 0, 0);
1170
                break;
1171
        default:
1172
                printf("DIAG - illegal constant node.\n");
1173
                break;
1174
        }
1175
}
1176
 
1177
ENODE *ENODE::GetConstantHex(std::ifstream& ifs)
1178
{
1179
        static char buf[4000];
1180
        ENODE *ep;
1181
 
1182
        ep = allocEnode();
1183
        ifs.read(buf, 2);
1184
        buf[2] = '\0';
1185
        ep->nodetype = (e_node)strtol(buf, nullptr, 16);
1186
        switch (ep->nodetype) {
1187
        case en_autofcon:
1188
                ifs.read(buf, 8);
1189
                buf[8] = '\0';
1190
                ep->i = strtol(buf, nullptr, 16);
1191
                break;
1192
        case en_fcon:
1193
                goto j1;
1194
        case en_autovcon:
1195
        case en_autocon:
1196
        case en_icon:
1197
                ifs.read(buf, 8);
1198
                buf[8] = '\0';
1199
                ep->i = strtol(buf, nullptr, 16);
1200
                break;
1201
        case en_labcon:
1202
j1:             ;
1203
        }
1204
}
1205
 
1206
void ENODE::PutConstantHex(txtoStream& ofs, unsigned int lowhigh, unsigned int rshift)
1207
{
1208
        // ASM statment text (up to 3500 chars) may be placed in the following buffer.
1209
        static char buf[4000];
1210
 
1211
        ofs.printf("N%02X", nodetype);
1212
        switch (nodetype)
1213
        {
1214
        case en_autofcon:
1215
                sprintf_s(buf, sizeof(buf), "%08LLX", i);
1216
                ofs.write(buf);
1217
                break;
1218
        case en_fcon:
1219
                goto j1;
1220
        case en_autovcon:
1221
        case en_autocon:
1222
        case en_icon:
1223
                sprintf_s(buf, sizeof(buf), "%08llX", i);
1224
                ofs.write(buf);
1225
                break;
1226
        case en_labcon:
1227
        j1:
1228
                sprintf_s(buf, sizeof(buf), "%s_%lld:", GetNamespace(), i);
1229
                ofs.write(buf);
1230
                break;
1231
        case en_clabcon:
1232
                sprintf_s(buf, sizeof(buf), "%s_%lld:", GetNamespace(), i);
1233
                ofs.write(buf);
1234
                break;
1235
        case en_nacon:
1236
                sprintf_s(buf, sizeof(buf), "%s:", (char *)sp->c_str());
1237
                ofs.write(buf);
1238
                break;
1239
        case en_cnacon:
1240
                sprintf_s(buf, sizeof(buf), "%s:", (char *)msp->c_str());
1241
                ofs.write(buf);
1242
                break;
1243
        case en_add:
1244
                p[0]->PutConstantHex(ofs, 0, 0);
1245
                ofs.write("+");
1246
                p[1]->PutConstantHex(ofs, 0, 0);
1247
                break;
1248
        case en_sub:
1249
                p[0]->PutConstantHex(ofs, 0, 0);
1250
                ofs.write("-");
1251
                p[1]->PutConstantHex(ofs, 0, 0);
1252
                break;
1253
        case en_uminus:
1254
                ofs.write("-");
1255
                p[0]->PutConstantHex(ofs, 0, 0);
1256
                break;
1257
        default:
1258
                printf("DIAG - illegal constant node.\n");
1259
                break;
1260
        }
1261
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.