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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [asmdata.cpp] - Blame information for rev 126

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    asmdata.cpp
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU core
6
//
7
// Purpose:     Like asmdata.h, this contains necessary data structures for the
8
//              assembler.  Specifically, in C/C++ fashion, this contains most
9
//              of the code for actually building such structures.
10
//
11
// Creator:     Dan Gisselquist, Ph.D.
12 69 dgisselq
//              Gisselquist Technology, LLC
13 13 dgisselq
//
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// Copyright (C) 2015, Gisselquist Technology, LLC
17
//
18
// This program is free software (firmware): you can redistribute it and/or
19
// modify it under the terms of  the GNU General Public License as published
20
// by the Free Software Foundation, either version 3 of the License, or (at
21
// your option) any later version.
22
//
23
// This program is distributed in the hope that it will be useful, but WITHOUT
24
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
25
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
// for more details.
27
//
28
// You should have received a copy of the GNU General Public License along
29
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
30
// target there if the PDF file isn't present.)  If not, see
31
// <http://www.gnu.org/licenses/> for a copy.
32
//
33
// License:     GPL, v3, as defined and found on www.gnu.org,
34
//              http://www.gnu.org/licenses/gpl.html
35
//
36
//
37
////////////////////////////////////////////////////////////////////////////////
38
 
39
#include <stdlib.h>
40
#include <assert.h>
41
#include <string.h>
42
#include "asmdata.h"
43
 
44
extern  void    yyerror(const char *str);
45
 
46
unsigned int    ILINE::eval(const int lno) {
47
        return (lno==0)?m_in:DEFAULT_LINE;
48
}
49
 
50
unsigned int    VLINE::eval(const int lno) {
51
        return DEFAULT_LINE;
52
}
53
 
54
unsigned int    DLINE::eval(const int lno) {
55
        return (lno==0)?m_data:DEFAULT_LINE;
56
}
57
 
58
void LLINE::addline(ASMLINE *line) {
59
        if (m_lines != NULL) {
60
                ASMLINE **nwlines = new ASMLINE *[m_nlines+1];
61
                for(int i=0; i<m_nlines; i++)
62
                        nwlines[i] = m_lines[i];
63
                delete[] m_lines;
64
                nwlines[m_nlines++] = line;
65
 
66
                m_lines = nwlines;
67
        } else {
68
                m_lines = new ASMLINE *[1];
69
                m_lines[m_nlines++] = line;
70
        }
71 26 dgisselq
 
72
        if (m_lineno > line->m_lineno)
73
                m_lineno = line->m_lineno;
74 13 dgisselq
};
75
 
76
bool    LLINE::isdefined(void) {
77
        for(int i=0; i<m_nlines; i++)
78
                if (!m_lines[i]->isdefined())
79
                return false;
80
        return true;
81
};
82
 
83
LLINE::~LLINE(void) {
84
        for(int i=0; i<m_nlines; i++)
85
                delete m_lines[i];
86
        delete m_lines;
87
}
88
 
89
unsigned int    LLINE::eval(const int lno) {
90
        return (lno < m_nlines)?m_lines[lno]->eval(0) : DEFAULT_LINE;
91
}
92
 
93
// int  m_op; // An operator
94
// AST  *m_left, *m_right;
95
 
96
int     AST_BRANCH::eval(void) {
97
        int     lft = m_left->eval(), rht = m_right->eval();
98
 
99
        switch(m_op) {
100
                case '+':       return lft + rht;
101
                case '-':       return lft - rht;
102
                case '*':       return lft * rht;
103
                case '/':       return lft / rht;
104
                case '%':       return lft % rht;
105
                case '^':       return lft ^ rht;
106
                case '|':       return lft | rht;
107
                case '&':       return lft & rht;
108
                case '~':       return ~lft;
109
                default:        yyerror("Unknown operation"); return lft;
110
        }
111
} void  AST_BRANCH::reduce(void) {
112
        if ((m_left)&&(m_left->m_node_type != 'N')&&(m_left->isdefined())) {
113
                int     val = m_left->eval();
114
                delete  m_left;
115
                m_left = new AST_NUMBER(val);
116
        } else
117
                m_left->reduce();
118
        if ((m_right)&&(m_right->m_node_type != 'N')&&(m_right->isdefined())) {
119
                int     val = m_right->eval();
120
                delete  m_right;
121
                m_right = new AST_NUMBER(val);
122
        } else
123
                m_right->reduce();
124
}
125
 
126
AST_IDENTIFIER::AST_IDENTIFIER(AST *ida, const char *idb) {
127
        m_node_type = 'I';
128
        m_id = ((AST_IDENTIFIER*)ida)->m_id + "." + std::string(idb);
129
        delete ida;
130
}
131
 
132
bool    AST_IDENTIFIER::isdefined(void) {
133
        bool    answer = stb_isdefined(m_id);
134
        return answer;
135
} int   AST_IDENTIFIER::eval(void) {
136
        return stb_value(m_id);
137
} void  AST_IDENTIFIER::reduce(void) {}
138
 
139
bool    AST_LABEL::isdefined(void) {
140
        bool    answer = stb_isdefined(m_label);
141
        return answer;
142
} int   AST_LABEL::eval(void) {
143
        return stb_value(m_label);
144
} void  AST_LABEL::reduce(void) {}
145
 
146
 
147
int     AST_NUMBER::eval(void) {
148
        return m_val;
149
} void  AST_NUMBER::reduce(void) {}
150
 
151
void    OBJFILE::open(const char *fname) {
152
        if ((m_fp != NULL)||(m_pc != 0l)) {
153
                fprintf(stderr, "Error: Can only change file names at startup\n");
154
                exit(-2);
155
        }
156
        m_fp = fopen(fname, "w");
157
        if (m_fp == NULL) {
158
                fprintf(stderr, "Cannot open %s for writing\n", fname);
159
                perror("O/S Err:");
160
                m_fp = fopen("/dev/null","w");
161
        }
162
}
163
 
164
void    OBJFILE::operator+=(ASMLINE *ln) {
165
        unsigned int    buf[1];
166
        int             nlines = ln->nlines();
167
 
168
        if (!ln->isdefined()) {
169
                // fprintf(stderr, "%08x: Adding undefined line:\n", m_pc);
170
                // ((TLINE *)ln)->dump(stderr);
171
                m_tbl.insert(m_tbl.end(), SAVED_ASMLINE(m_pc,ln));
172
        /*
173
        } else {
174
                fprintf(stderr, "%08x: Adding to file:\n", m_pc);
175
                ((TLINE *)ln)->dump(stderr);
176
        */
177
        }
178
        for(int i=0; i<nlines; i++) {
179
                buf[0] = ln->eval(i);
180
                if (m_fp) fwrite(buf, sizeof(ZIPI), 1, m_fp);
181
                m_pc++;
182
        }
183
}
184
 
185
bool    OBJFILE::reduce(void) {
186
        SVDTBL::iterator        i;
187
        bool    all_reduced = true;
188
 
189
        // printf("Checking for reductions\n");
190
        unsigned int tmp = m_pc;
191
        for(i=m_tbl.begin(); i != m_tbl.end(); i++) {
192
                // printf("LINE %08x\n", i->m_pc);
193
                ASMLINE *ln = i->m_ln;
194
                m_pc = i->m_pc;
195
                if (ln->isdefined()) {
196
                        // printf("PC = 0x%08x reduces\n", i->m_pc);
197
                        fseek(m_fp, sizeof(ZIPI)*i->m_pc, SEEK_SET);
198
                        for(int k=0; k< ln->nlines(); k++) {
199
                                ZIPI    buf[1];
200
                                m_pc = i->m_pc+k;
201
                                buf[0] = ln->eval(k);
202
                                // printf("\t0x%08x -> %08x\n", i->m_pc+k,
203
                                        // buf[0]);
204
                                fwrite(buf, sizeof(ZIPI), 1, m_fp);
205
                        }
206
                } else {
207 26 dgisselq
                        fprintf(stderr, "Line %d contains an undefined symbol: ", ln->m_lineno);
208 13 dgisselq
                        fprintf(stderr, "PC = 0x%08x isn\'t ready yet\n", i->m_pc);
209
                        i->m_ln->dump(stderr);
210
                        all_reduced = false;
211
                }
212
        } m_pc = tmp;
213
        return all_reduced;
214
}
215
 
216
bool    fitsin(const int v, const int b) {
217
        if (v>0)
218
                return (v < (1<<(b-1)));
219
        else
220
                return (-v <= (1<<b));
221
}
222
 
223
#define BLD_DUALOP(OP)                                                  \
224
        if (m_opa == zp.ZIP_Rnone)                                      \
225
                yyerror("Err: Dual Ops need a result register");        \
226
        if (m_opb != zp.ZIP_Rnone) {                                    \
227 69 dgisselq
                if(!fitsin(imm, 14))                                    \
228
                        yyerror("14-bit: Immediate out of range");      \
229 13 dgisselq
                in = zp.OP(m_cond,imm,m_opb,m_opa);                     \
230
        } else {                                                        \
231 69 dgisselq
                if(!fitsin(imm, 18))                                    \
232
                        yyerror("18-bit: Immediate out of range");      \
233 13 dgisselq
                in = zp.OP(m_cond,imm,m_opa);                           \
234
        }
235
 
236
#define BLD_BRANCH(OP,CND)                                              \
237 69 dgisselq
        if (fitsin(offset, 13))                                         \
238 13 dgisselq
                in = zp.OP(offset);                                     \
239 69 dgisselq
        else if (fitsin(offset, 18))                                    \
240 13 dgisselq
                in = zp.op_add(zp.CND, offset, zp.ZIP_PC);              \
241
        else { in = zp.OP(offset); yyerror("LONG JUMP NOT SUPPORTED"); }
242
 
243
ASMLINE *TLINE::eval(void) {
244
        ZIPI    in;
245
        ZPARSER zp;
246
        int     offset = 0, imm = 0;
247
 
248
        if (m_opcode != OP_MOV) {
249
                if ( ((m_opa!=zp.ZIP_Rnone)&&(m_opa > zp.ZIP_PC))
250
                        || ((m_opb!=zp.ZIP_Rnone)&&(m_opb > zp.ZIP_PC))  )
251
                        yyerror("Only move instructions can reference user regs");
252
        }
253
 
254
        // Offset used in jumps
255
        if (m_imm) {
256
                imm = m_imm->eval();
257
                offset = imm-objcode.pc()-1;
258
 
259
                if (m_opb == zp.ZIP_PC)
260
                        imm = offset;
261
        }
262
 
263
        switch(m_opcode) {
264
                case OP_CMP:
265
                        BLD_DUALOP(op_cmp)
266
                        break;
267
                case OP_TST:
268
                        BLD_DUALOP(op_tst)
269
                        break;
270
                case OP_MOV:
271
                        if ((m_opa == zp.ZIP_Rnone)||(m_opb == zp.ZIP_Rnone)) {
272
                                yyerror("Moves can only occurr between registers");
273
                                fprintf(stderr, "m_opa = %d, m_opb = %d\n", m_opa, m_opb);
274
                                fprintf(stderr, "m_imm = %d\n", imm);
275 69 dgisselq
                        } else if (!fitsin(imm, 13))
276 13 dgisselq
                                yyerror("Immediate overflow on move");
277
                        in = zp.op_mov(m_cond, imm, m_opb, m_opa);
278
                        break;
279
                case OP_LDIHI:
280
                        if ((imm & (-1<<16))!=0)
281
                                yyerror("16-bit Immediate out of range");
282
                        if (m_opb != zp.ZIP_Rnone)
283
                                yyerror("LDIHI cannot accept OP-B registers");
284
                        if (m_opa == zp.ZIP_Rnone)
285
                                yyerror("LDIHI needs a register result");
286
                        in = zp.op_ldihi(m_cond, imm, m_opa);
287
                        break;
288
                case OP_LDILO:
289
                        if ((imm & (-1<<16))!=0)
290
                                yyerror("16-bit Immediate out of range");
291
                        if (m_opb != zp.ZIP_Rnone)
292
                                yyerror("LDIHI cannot accept OP-B registers");
293
                        if (m_opa == zp.ZIP_Rnone)
294
                                yyerror("LDIHI needs a register result");
295
                        if ((imm & (-1<<16))!=0)
296
                                yyerror("16-bit Immediate out of range");
297
                        in = zp.op_ldilo(m_cond, imm, m_opa);
298
                        break;
299 26 dgisselq
                case OP_MPYU:
300
                        if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC)
301
                                ||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC))
302
                                yyerror("MPYU does not support PC or CC register operands or results");
303
                        else if (m_opb == zp.ZIP_Rnone)
304
                                in = zp.op_mpyu(m_cond, imm, m_opa);
305
                        else
306
                                in = zp.op_mpyu(m_cond, imm, m_opb, m_opa);
307 13 dgisselq
                        break;
308 26 dgisselq
                case OP_MPYS:
309
                        if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC)
310
                                ||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC))
311
                                yyerror("MPYS does not support PC or CC register operands or results");
312
                        else if (m_opb == zp.ZIP_Rnone)
313
                                in = zp.op_mpys(m_cond, imm, m_opa);
314
                        else
315
                                in = zp.op_mpys(m_cond, imm, m_opb, m_opa);
316
                        break;
317 13 dgisselq
                case OP_ROL:
318
                        if (m_opa == zp.ZIP_Rnone)
319
                                yyerror("ROL needs a register result");
320
                        if (m_opb != zp.ZIP_Rnone)
321
                                in = zp.op_rol(m_cond, imm, m_opb, m_opa);
322
                        else
323
                                in = zp.op_rol(m_cond, imm, m_opa);
324
                        break;
325
                case OP_SUB:
326
                        BLD_DUALOP(op_sub)
327
                        break;
328
                case OP_AND:
329
                        BLD_DUALOP(op_and)
330
                        break;
331
                case OP_ADD:
332
                        BLD_DUALOP(op_add)
333
                        break;
334
                case OP_OR:
335
                        BLD_DUALOP(op_or)
336
                        break;
337
                case OP_XOR:
338
                        BLD_DUALOP(op_xor)
339
                        break;
340
                case OP_LSL:
341
                        BLD_DUALOP(op_lsl)
342
                        break;
343
                case OP_ASR:
344
                        BLD_DUALOP(op_asr)
345
                        break;
346
                case OP_LSR:
347
                        BLD_DUALOP(op_lsr)
348
                        break;
349
                case OP_LOD:
350
                        if (m_opb != zp.ZIP_Rnone)
351
                                in = zp.op_lod(m_cond, imm, m_opb, m_opa);
352
                        else
353
                                in = zp.op_lod(m_cond, imm, m_opa);
354
                        break;
355
                case OP_STO:
356
                        if (m_opb != zp.ZIP_Rnone)
357
                                in = zp.op_sto(m_cond, m_opa, imm, m_opb);
358
                        else
359
                                in = zp.op_sto(m_cond, m_opa, imm);
360
                        break;
361 69 dgisselq
                case OP_BREV:
362
                        BLD_DUALOP(op_brev);
363
                        break;
364
                case OP_POPC:
365
                        BLD_DUALOP(op_popc);
366
                        break;
367 13 dgisselq
                case OP_LDI:
368 69 dgisselq
                        if ((!fitsin(imm, 23))||(m_cond != zp.ZIPC_ALWAYS)) {
369 13 dgisselq
                                if (m_opa == zp.ZIP_PC)
370
                                        yyerror("Cannot LDI 32-bit addresses into PC register!");
371
                                LLINE *lln = new LLINE;
372
                                lln->addline(new ILINE(zp.op_ldihi(m_cond, (imm>>16)&0x0ffff, m_opa)));
373
                                lln->addline(new ILINE(zp.op_ldilo(m_cond, imm&0x0ffff, m_opa)));
374 26 dgisselq
                                lln->m_lineno = m_lineno;
375 13 dgisselq
                                return lln;
376
                        } else
377
                                in = zp.op_ldi(imm, m_opa);
378
                        break;
379 69 dgisselq
                case OP_DIVU:
380
                        BLD_DUALOP(op_divu);
381
                        break;
382
                case OP_DIVS:
383
                        BLD_DUALOP(op_divs);
384
                        break;
385 13 dgisselq
                case OP_CLRF:
386
                        in = zp.op_clrf(m_cond, m_opb);
387
                        break;
388
                case OP_NOT:
389
                        in = zp.op_not(m_cond, m_opb);
390
                        break;
391 26 dgisselq
                case OP_NEG:
392
                        if (m_cond != zp.ZIPC_ALWAYS) {
393 36 dgisselq
                                LLINE *lln = new LLINE;
394
                                lln->addline(new ILINE(zp.op_mov(m_cond,-1,m_opb,m_opb)));
395
                                lln->addline(new ILINE(zp.op_not(m_cond,m_opb)));
396
                                return lln;
397 26 dgisselq
                        } else {
398
                                LLINE *lln = new LLINE;
399
                                lln->addline(new ILINE(zp.op_not(m_opb)));
400
                                lln->addline(new ILINE(zp.op_add(1,m_opb)));
401
                                return lln;
402
                        }break;
403 13 dgisselq
                case OP_JMP:
404 60 dgisselq
                        if (m_opb == zp.ZIP_Rnone) {
405 13 dgisselq
                                if (m_cond != zp.ZIPC_ALWAYS)
406
                                        yyerror("JMP: Conditions are not allowed for absolute jumps.");
407 69 dgisselq
                                imm &= (1<<23)-1;
408
                                if (!fitsin(imm, 23))
409 13 dgisselq
                                        yyerror("JMP: Absolute jump address out of range");
410 60 dgisselq
                                in = zp.op_ldi(imm, zp.ZIP_PC);
411 69 dgisselq
                        } else if (fitsin(imm,13)) {
412 60 dgisselq
                                in = zp.op_mov(m_cond, imm, m_opb, zp.ZIP_PC);
413 69 dgisselq
                        } else if (fitsin(imm,18))
414 60 dgisselq
                                in = zp.op_add(m_cond, imm, m_opb, zp.ZIP_PC);
415
                        else
416
                                yyerror("JMP: Immediate out of range");
417
                        break;
418 13 dgisselq
                case OP_BRA:
419
                        BLD_BRANCH(op_bra,ZIPC_ALWAYS)
420
                        break;
421
                case OP_BZ:
422
                        BLD_BRANCH(op_brz,ZIPC_Z)
423
                        break;
424
                case OP_BNZ:
425
                        BLD_BRANCH(op_bnz,ZIPC_NZ)
426
                        break;
427
                case OP_BGE:
428
                        BLD_BRANCH(op_bge,ZIPC_GE)
429
                        break;
430
                case OP_BGT:
431
                        BLD_BRANCH(op_bgt,ZIPC_GT)
432
                        break;
433
                case OP_BLT:
434
                        BLD_BRANCH(op_blt,ZIPC_LT)
435
                        break;
436
                case OP_BRC:
437
                        BLD_BRANCH(op_brc,ZIPC_C)
438
                        break;
439
                case OP_BRV:
440
                        BLD_BRANCH(op_brv,ZIPC_V)
441
                        break;
442
                case OP_CLR:
443 46 dgisselq
                        if((m_cond == zp.ZIPC_ALWAYS))
444
                                in = zp.op_clr(m_opb);
445
                        else
446
                                in = zp.op_clrf(m_cond, m_opb);
447 13 dgisselq
                        break;
448
                case OP_TRAP:
449
                        if((m_opb == zp.ZIP_Rnone)&&(m_cond == zp.ZIPC_ALWAYS))
450
                                in = zp.op_ldi(imm, zp.ZIP_CC);
451 60 dgisselq
                        else if((m_opb == zp.ZIP_Rnone)&&((imm&0x0ffdf)==imm))
452
                                in = zp.op_ldilo(m_cond, imm & 0x0ffdf, zp.ZIP_CC);
453 69 dgisselq
                        else if((m_opb != zp.ZIP_Rnone)&&(fitsin(imm, 13)))
454 13 dgisselq
                                in = zp.op_mov(m_cond, imm, m_opb, zp.ZIP_CC);
455
                        else {
456
                                yyerror("Illegal trap!");
457
                                in = zp.op_trap(m_cond, 0);
458
                        }
459
                        break;
460 69 dgisselq
                case OP_RETN:   // yywarn("RETN opcode is deprecated");
461
                                in = zp.op_lod(m_cond, imm, m_opb, m_opa);
462
                                in = zp.op_lod(m_cond, -1, zp.ZIP_SP, zp.ZIP_PC);
463
                        break;
464 126 dgisselq
                case OP_MPY:
465
                        if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC)
466
                                ||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC))
467
                                yyerror("MPY does not support PC or CC register operands or results");
468
                        else if (m_opb == zp.ZIP_Rnone)
469
                                in = zp.op_mpy(m_cond, imm, m_opa);
470
                        else
471
                                in = zp.op_mpy(m_cond, imm, m_opb, m_opa);
472
                        break;
473
                case OP_MPYUHI:
474
                        if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC)
475
                                ||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC))
476
                                yyerror("MPY does not support PC or CC register operands or results");
477
                        else if (m_opb == zp.ZIP_Rnone)
478
                                in = zp.op_mpyuhi(m_cond, imm, m_opa);
479
                        else
480
                                in = zp.op_mpyuhi(m_cond, imm, m_opb, m_opa);
481
                        break;
482
                case OP_MPYSHI:
483
                        if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC)
484
                                ||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC))
485
                                yyerror("MPY does not support PC or CC register operands or results");
486
                        else if (m_opb == zp.ZIP_Rnone)
487
                                in = zp.op_mpyshi(m_cond, imm, m_opa);
488
                        else
489
                                in = zp.op_mpyshi(m_cond, imm, m_opb, m_opa);
490
                        break;
491 13 dgisselq
                case OP_HALT:   in = zp.op_halt(m_cond); break;
492
                case OP_RTU:    in = zp.op_rtu(m_cond); break;
493
                case OP_BUSY:   in = zp.op_busy(m_cond); break;
494 69 dgisselq
                case OP_NOOP:   in = zp.op_noop(); break;
495 13 dgisselq
                case OP_BREAK:  in = zp.op_break(); break;
496 69 dgisselq
                case OP_LOCK:   in = zp.op_lock(); break;
497 96 dgisselq
                case OP_LJMP:   in = zp.op_ljmp(); break;
498 13 dgisselq
                case OP_NONE:
499
                default:        { char ebuf[256]; sprintf(ebuf, "Unrecognized OP-Code, %d, NONE = %d, CLR=%d", m_opcode, OP_NONE, OP_CLR);
500
                                yyerror(ebuf);
501
                                in = zp.op_noop(); break;
502
                                }
503 26 dgisselq
        }
504
        ILINE   *rs = new ILINE(in);
505
        rs->m_lineno = m_lineno;
506 13 dgisselq
}
507
 
508
int     TLINE::nlines(void)  {
509
        if ((m_opcode == OP_LDI)&&( (!(m_imm->isdefined()))
510
                        || (m_cond != ZPARSER::ZIPC_ALWAYS)
511 69 dgisselq
                        || (!fitsin(m_imm->eval(), 23)) )) {
512 13 dgisselq
                return 2;
513
        }
514
        return 1;
515
}
516
 
517
unsigned int    TLINE::eval(const int lno) {
518
        if (!isdefined())
519
                return DEFAULT_LINE;
520
        else {
521
                ASMLINE *ln = this->eval();
522
                unsigned int val = ln->eval(lno);
523
                delete ln;
524
                return val;
525
        }
526
}
527
 
528
void    TLINE::dump(FILE *fp) {
529
        if (m_state == 'V')
530 26 dgisselq
                fprintf(fp, "Void @%d\n", m_lineno);
531 13 dgisselq
        else if (m_state != 'T')
532
                fprintf(fp, "TLINE state != T (== %c)\n", m_state);
533
        else {
534 26 dgisselq
                fprintf(fp, "TLINE @%d\n", m_lineno);
535 13 dgisselq
                switch(m_opcode) {
536
                case OP_CMP: fprintf(fp, "\tTLINE OP   = CMP\n");
537
                        break;
538
                case OP_TST: fprintf(fp, "\tTLINE OP   = TST\n");
539
                        break;
540
                case OP_MOV: fprintf(fp, "\tTLINE OP   = MOV\n");
541
                        break;
542 26 dgisselq
                case OP_LDIHI:fprintf(fp,"\tTLINE OP   = LDIHI\n");
543 13 dgisselq
                        break;
544 26 dgisselq
                case OP_LDILO:fprintf(fp,"\tTLINE OP   = LDILO\n");
545 13 dgisselq
                        break;
546 26 dgisselq
                case OP_MPYU: fprintf(fp,"\tTLINE OP   = MPYU\n");
547 13 dgisselq
                        break;
548 26 dgisselq
                case OP_MPYS: fprintf(fp,"\tTLINE OP   = MPYS\n");
549
                        break;
550 13 dgisselq
                case OP_ROL: fprintf(fp, "\tTLINE OP   = ROL\n");
551
                        break;
552
                case OP_SUB: fprintf(fp, "\tTLINE OP   = SUB\n");
553
                        break;
554
                case OP_AND: fprintf(fp, "\tTLINE OP   = AND\n");
555
                        break;
556
                case OP_ADD: fprintf(fp, "\tTLINE OP   = ADD\n");
557
                        break;
558
                case OP_OR: fprintf(fp, "\tTLINE OP   = OR\n");
559
                        break;
560
                case OP_XOR: fprintf(fp, "\tTLINE OP   = XOR\n");
561
                        break;
562
                case OP_LSL: fprintf(fp, "\tTLINE OP   = LSL\n");
563
                        break;
564
                case OP_ASR: fprintf(fp, "\tTLINE OP   = ASR\n");
565
                        break;
566
                case OP_LSR: fprintf(fp, "\tTLINE OP   = LSR\n");
567
                        break;
568
                case OP_LOD: fprintf(fp, "\tTLINE OP   = LOD\n");
569
                        break;
570
                case OP_STO: fprintf(fp, "\tTLINE OP   = STO\n");
571
                        break;
572
                case OP_LDI: fprintf(fp, "\tTLINE OP   = LDI\n");
573
                        break;
574
                case OP_CLRF: fprintf(fp, "\tTLINE OP   = CLRF\n");
575
                        break;
576
                case OP_NOT: fprintf(fp, "\tTLINE OP   = NOT\n");
577
                        break;
578
                case OP_JMP: fprintf(fp, "\tTLINE OP   = JMP\n");
579
                        break;
580
                case OP_BRA: fprintf(fp, "\tTLINE OP   = BRA\n");
581
                        break;
582
                case OP_BZ:
583
                case OP_BNZ:
584
                case OP_BGE:
585
                case OP_BGT:
586
                case OP_BLT:
587
                case OP_BRC:
588
                case OP_BRV:
589
                        fprintf(fp, "\tTLINE OP   = BRA.C\n");
590
                        break;
591
                case OP_CLR: fprintf(fp, "\tTLINE OP   = CLR\n");
592
                        break;
593 26 dgisselq
                case OP_NEG: fprintf(fp, "\tTLINE OP   = NEG\n");
594
                        break;
595 13 dgisselq
                case OP_TRAP: fprintf(fp, "\tTLINE OP   = TRAP\n");
596
                        break;
597
                case OP_HALT: fprintf(fp, "\tTLINE OP   = HALT\n");
598
                        break;
599
                case OP_RTU: fprintf(fp, "\tTLINE OP   = RTU\n");
600
                        break;
601
                case OP_BUSY: fprintf(fp, "\tTLINE OP   = BUSY\n");
602
                        break;
603
                case OP_BREAK: fprintf(fp, "\tTLINE OP   = BREAK\n");
604
                        break;
605
                case OP_NOOP: fprintf(fp, "\tTLINE OP   = NOOP\n");
606 69 dgisselq
                case OP_LOCK: fprintf(fp, "\tTLINE OP   = LOCK\n");
607 13 dgisselq
                        break;
608
                case OP_NONE:
609
                default:
610
                        fprintf(fp, "\tTLINE OP   = (Unrecognized, %d)\n", m_opcode);
611
                                break;
612
                }
613 34 dgisselq
                if (m_cond == 0)
614
                        fprintf(fp, "\tTLINE COND = (Always)\n");
615
                else
616
                        fprintf(fp, "\tTLINE COND = %s\n", zop_ccstr[m_cond&0x07]);
617 13 dgisselq
                if (m_imm == NULL)
618
                        fprintf(fp, "\tTLINE imm  = (NULL)\n");
619
                else if (!m_imm->isdefined()) {
620
                        m_imm->reduce();
621
                        fprintf(fp, "\tTLINE imm  = ");
622
                        m_imm->dump(fp);
623
                        fprintf(fp, "\n");
624
                } else
625
                        fprintf(fp, "\tTLINE imm  = %d\n", m_imm->eval());
626 34 dgisselq
                if (m_opb != ZPARSER::ZIP_Rnone)
627
                        fprintf(fp, "\tTLINE opb  = %d\n", m_opb);
628
                if (m_opa != ZPARSER::ZIP_Rnone)
629
                        fprintf(fp, "\tTLINE opa  = %d\n", m_opa);
630 13 dgisselq
        }
631
}
632
 
633
 
634
// Now, for our symbol table
635
class   SYMTABLE_ENTRY {
636
private:
637
        int     m_recursion_check;
638
 
639
        std::string     &trim(std::string &s) {
640
                std::string::iterator   ptr = s.end()-1;
641
 
642
                while((ptr >= s.begin())&&(isspace(*ptr)))
643
                        *ptr-- = '\0';
644
                if (*ptr == ':')
645
                        *ptr-- = '\0';
646
 
647
                // printf("STORING: %s\n", s.c_str());
648
 
649
                return s;
650
        }
651
 
652
public:
653
        std::string     m_name;
654
        AST             *m_value;
655
        SYMTABLE_ENTRY(const char *str) : m_recursion_check(0), m_name(str), m_value(NULL) {
656
                trim(m_name);
657
        } SYMTABLE_ENTRY(const char *str, AST *v) : m_recursion_check(0), m_name(str), m_value(v) {
658
                trim(m_name);
659
        } ~SYMTABLE_ENTRY(void) {
660 46 dgisselq
                if (m_value)
661
                        delete m_value;
662 13 dgisselq
        }
663
 
664
        SYMTABLE_ENTRY &operator=(AST *new_value) {
665
                if (m_value)
666
                        delete  m_value;
667
                m_value = new_value;
668
        }
669
 
670
        bool    isdefined(void) {
671
                if (m_recursion_check > 0) {
672
                        fprintf(stderr, "RECURSION DETECTED! Symbol: %s\n",
673
                                m_name.c_str());
674
                        return false;
675
                }
676
                m_recursion_check = 1;
677
                if (m_value->m_node_type != 'N')
678
                        m_value->reduce();
679
                bool    answer = m_value->isdefined();
680
                m_recursion_check = 0;
681
                return answer;
682
        }
683
        int     val(void) {
684
                if ((m_value->isdefined())&&(m_value->m_node_type != 'N')) {
685
                        int     v = m_value->eval();
686
                        AST     *tmp;
687
                        tmp = m_value;
688
                        m_value = new AST_NUMBER(v);
689
                        delete tmp;
690
                } return (m_value->eval());
691
        }
692
        void    dump(FILE *fp) { m_value->dump(fp); }
693
};
694
 
695
class   SYMBOL_TABLE    {
696
private:
697
        typedef SYMTABLE_ENTRY  *TBLV;
698
        typedef std::list<TBLV> TBLT;
699
 
700
        TBLT    m_tbl;
701
 
702
        TBLT::iterator  lookup(const char *str) {
703
                TBLT::iterator  i = m_tbl.begin();
704
                for(; (i!=m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())>0);
705
                                i++)
706
                        ;
707
                if ((i != m_tbl.end())&&(strcmp(str,(*i)->m_name.c_str())==0))
708
                        return i;
709
                return  m_tbl.end();
710
        }
711
 
712
public:
713
        SYMBOL_TABLE(void) {}
714
        ~SYMBOL_TABLE(void) {
715
                TBLT::iterator i = m_tbl.begin();
716
                while(i != m_tbl.end()) {
717
                        delete (*i);
718 46 dgisselq
                        i = m_tbl.erase(i);
719 13 dgisselq
                }
720
        }
721
 
722
        void    define(const char *key, AST *value) {
723
                SYMTABLE_ENTRY  *v = new SYMTABLE_ENTRY(key, value);
724
                TBLT::iterator  i = m_tbl.begin();
725
                for(; (i!=m_tbl.end())&&(strcmp(key, (*i)->m_name.c_str())>0);
726
                                i++)
727
                        ;
728
                m_tbl.insert(i, v);
729
 
730
                /*
731
                fprintf(stderr, "Defining: %s = ", key);
732
                value->dump(stderr);
733
                fprintf(stderr, "\n");
734
                */
735
        }
736
 
737
        bool    isdefined(const char *key) {
738
                TBLT::iterator  i = lookup(key);
739
                if (i == m_tbl.end()) {
740
                        // fprintf(stderr, "%s is not in the symbol table\n", key);
741
                        return false;
742
                } else {
743
                        bool    defined = (*i)->isdefined();
744
                        /*
745
                        if (!defined) {
746
                                fprintf(stderr, "KEY: %s = ", key);
747
                                (*i)->dump(stderr);
748
                                fprintf(stderr, " is not yet defined\n");
749
                        } */
750
                        return (*i)->isdefined();
751
                }
752
        }
753
 
754
        int     value(const char *key) {
755
                TBLT::iterator  i = lookup(key);
756
                if (i == m_tbl.end())
757
                        return 0;
758
                else
759
                        return (*i)->val();
760
        }
761
};
762
 
763
SYMBOL_TABLE    *global_context = NULL, *file_context = NULL;
764
 
765
bool    stb_isdefined(const char *key) {
766
        if ((file_context)&&(file_context->isdefined(key)))
767
                return true;
768
        else
769
                return global_context->isdefined(key);
770
} int   stb_value(const char *key) {
771 46 dgisselq
        if ((file_context)&&(file_context->isdefined(key)))
772 13 dgisselq
                return file_context->value(key);
773
        else
774
                return global_context->value(key);
775
} void  stb_define(const char *key, AST *value) {
776
        file_context->define(key, value);
777
} void  gbl_define(const char *key, AST *value) {
778
        global_context->define(key, value);
779
}
780
 
781
void    create_new_context(void) {
782
        if (global_context == NULL)
783
                global_context = new SYMBOL_TABLE;
784
        if (file_context != NULL)
785
                delete file_context;
786
        file_context = new SYMBOL_TABLE;
787
}
788
 
789
 
790
// Convenience functions for accessing the symbol table
791
bool    stb_isdefined(const std::string &key) {
792
        bool answer = stb_isdefined(key.c_str());
793
        return answer;
794
} int   stb_value(const std::string &key) {
795
        return stb_value(key.c_str());
796
} void  stb_define(const std::string &key, AST *value) {
797
        stb_define(key.c_str(), value);
798
} void  gbl_define(const std::string &key, AST *value) {
799
        gbl_define(key.c_str(), value);
800
}
801
 
802
 

powered by: WebSVN 2.1.0

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