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

Subversion Repositories tinyvliw8

[/] [tinyvliw8/] [trunk/] [tools/] [asm/] [src/] [asm.c] - Blame information for rev 5

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

Line No. Rev Author Line
1 5 steckol
#include <sys/types.h>
2
#include <sys/stat.h>
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
#include <fcntl.h>
7
#include <unistd.h>
8
 
9
#include "instr.h"
10
#include "list.h"
11
 
12
static unsigned int _linenum;
13
static unsigned int _instr_addr;
14
 
15
extern FILE *yyin;
16
extern int yyparse();
17
 
18
static list_t _label = {&_label, &_label};
19
static list_t _instr = {&_instr, &_instr};
20
 
21
void instr_irq(unsigned char num)
22
{
23
        _instr_addr = 0x07fc + num;
24
}
25
 
26
void instr_add(const instr_t *instr, const unsigned char num)
27
{
28
        instr_vliw_t *ninstr;
29
 
30
        ninstr = malloc(sizeof(instr_vliw_t));
31
        if (NULL != ninstr) {
32
                unsigned int i;
33
 
34
                ninstr->addr = _instr_addr;
35
 
36
                ninstr->num = num;
37
                for (i = 0; i < num; i++) {
38
                        memcpy((char *) &ninstr->instr[i], (char *) &instr[i], sizeof(instr_t));
39
 
40
                        /* copy source list */
41
                        ninstr->instr[i].source.next->prev = &ninstr->instr[i].source;
42
                        ninstr->instr[i].source.prev->next = &ninstr->instr[i].source;
43
                }
44
 
45
                list_add_last(&_instr, &ninstr->list);
46
        }
47
 
48
        _instr_addr++;
49
}
50
 
51
void instr_label(const char *name)
52
{
53
        instr_label_t *n;
54
 
55
        n = malloc(sizeof(instr_label_t) + strlen(name) + 1);
56
        if (n) {
57
                LIST_INIT(&n->list);
58
                n->offset = _instr_addr;
59
 
60
                snprintf(n->name, 64, "%s", name);
61
 
62
                list_add(&_label, &n->list);
63
        }
64
 
65
        return;
66
}
67
 
68
void instr_add_source(list_t *head, instr_operand_type_t type, const void *data)
69
{
70
        instr_operand_t *op;
71
 
72
        op = (instr_operand_t *) malloc(sizeof(instr_operand_t));
73
        if (NULL != op) {
74
                op->type = type;
75
                switch (type) {
76
                  case instr_operand_type_reg:
77
                  case instr_operand_type_const:
78
                        op->value = *((int *) data);
79
                        break;
80
                  case instr_operand_type_label:
81
                        op->label = malloc(strlen((char *) data) + 1);
82
                        if (NULL != op->label) {
83
                                sprintf(op->label, "%s", (char *) data);
84
                        }
85
 
86
                        break;
87
                }
88
 
89
                list_add(head, &op->list);
90
        }
91
}
92
 
93
void instr_source_flag(list_t *source, unsigned char flag)
94
{
95
        if (source->prev != source) {
96
                instr_operand_t *op = LIST_ENTRY(source->prev, instr_operand_t, list);
97
 
98
                op->flags |= flag;
99
        }
100
}
101
 
102
void instr_add_dest(instr_operand_t *op, const unsigned char num)
103
{
104
        op->type = instr_operand_type_reg;
105
        op->value = num;
106
}
107
 
108
static unsigned int _get_symbol(const char *name)
109
{
110
        return 0x00;
111
}
112
 
113
static unsigned int _get_label(const char *name)
114
{
115
        if (NULL != name) {
116
                list_t *h;
117
 
118
                for (h = _label.next; h != &_label; h = h->next) {
119
                        instr_label_t *l;
120
 
121
                        l = LIST_ENTRY(h, instr_label_t, list);
122
 
123
                        if (0 == strcmp(l->name, name))
124
                                return l->offset;
125
                }
126
        }
127
 
128
        return 0x00;
129
}
130
 
131
static void _write_jmp(unsigned char *iw, instr_opcode_t opcode, const instr_operand_t *op)
132
{
133
        unsigned int addr;
134
 
135
        iw[0] = (0x07 << 5);
136
 
137
        switch (opcode) {
138
        case instr_opcode_jz:
139
                iw[0] |= (0x01 << 3);
140
                break;
141
        case instr_opcode_jc:
142
                iw[0] |= (0x02 << 3);
143
                break;
144
        case instr_opcode_jnz:
145
                iw[0] |= (0x03 << 3);
146
                break;
147
        default:
148
                /* nothing to do */;
149
        }
150
 
151
        addr = 0;
152
        if (instr_operand_type_const == op->type) {
153
                addr = op->value;
154
        } else if (instr_operand_type_label == op->type) {
155
                addr = _get_label(op->label);
156
        }
157
 
158
        iw[0] |= ((addr & 0x07ff) >> 8);
159
        iw[1] = addr & 0x00ff;
160
}
161
 
162
static void _write_ldst(unsigned char *iw, instr_opcode_t opcode, const instr_operand_t *dst, const instr_operand_t *src)
163
{
164
        switch (opcode) {
165
        case instr_opcode_ldi:
166
                iw[0] = (0x01 << 4);
167
                break;
168
        case instr_opcode_st:
169
                iw[0] = (0x02 << 4);
170
                break;
171
        case instr_opcode_sti:
172
                iw[0] = (0x03 << 4);
173
                break;
174
        default:
175
                iw[0] = 0x00;
176
                break;
177
        }
178
 
179
        if (instr_operand_type_reg == src->type) {
180
                iw[0] |= (0x01 << 3);
181
        }
182
 
183
        iw[0] |= dst->value & 0x07;
184
 
185
        switch (src->type) {
186
        case instr_operand_type_reg:
187
                iw[0] |= (0x01 << 3);
188
                iw[1] = src->value & 0x07;
189
 
190
                break;
191
        case instr_operand_type_const:
192
                iw[1] = src->value;
193
                break;
194
        case instr_operand_type_label:
195
                iw[1] = _get_symbol(src->label);
196
                break;
197
        }
198
}
199
 
200
static void _write_sh(unsigned char *iw, instr_opcode_t opcode, const instr_operand_t *dst, const instr_operand_t *src)
201
{
202
        iw[0] = (0x03 << 5);
203
        iw[1] = 0x00;
204
 
205
        switch (opcode) {
206
        case instr_opcode_rlc:
207
                iw[1] |= (0x01 << 3);
208
                break;
209
        case instr_opcode_rrc:
210
                iw[1] |= (0x01 << 3);
211
        case instr_opcode_rra:
212
                iw[0] |= (0x01 << 3);
213
                break;
214
        default:
215
                /* nothing to do */;
216
        }
217
 
218
        iw[0] |= dst->value & 0x07;
219
        iw[1] |= src->value & 0x07;
220
}
221
 
222
#define _SRC_FIRST(src)  (src)->next != src ? LIST_ENTRY((src)->next, instr_operand_t, list) : NULL
223
 
224
static void _write_src(unsigned char *iw, const instr_operand_t *dst, const list_t *src_l)
225
{
226
        instr_operand_t *src = _SRC_FIRST(src_l);
227
 
228
        if (instr_operand_type_const == src->type) {
229
                iw[0] |= (0x01 << 3);
230
                iw[1] = src->value & 0x00ff;
231
        } else if (instr_operand_type_reg == src->type) {
232
                iw[1] = src->value & 0x07;
233
                if (0 != (src->flags & INSTR_FLAG_TILDE))
234
                        iw[1] |= (0x01 << 3);
235
 
236
                if (src->list.next != src_l) {
237
                        src = LIST_ENTRY(src->list.next, instr_operand_t, list);
238
 
239
                        iw[1] |= (src->value & 0x07) << 4;
240
                        if (0 != (src->flags & INSTR_FLAG_TILDE))
241
                                iw[1] |= (0x01 << 7);
242
                } else {
243
                        iw[1] |= (dst->value & 0x07) << 4;
244
                }
245
        }
246
}
247
 
248
static void _write_add(unsigned char *iw, unsigned char carry, const instr_operand_t *dst, const list_t *src_l)
249
{
250
        iw[0] = (0x02 << 5);
251
        if (0 != carry)
252
                iw[0] |= (0x02 << 3);
253
 
254
        iw[0] |= dst->value & 0x07;
255
 
256
        _write_src(iw, dst, src_l);
257
}
258
 
259
static void _write_mov(unsigned char *iw, const instr_operand_t *dst, const instr_operand_t *src)
260
{
261
        iw[0] = (0x03 << 5);
262
        iw[0] |= (0x02 << 3);
263
 
264
        iw[0] |= dst->value & 0x07;
265
 
266
        if (instr_operand_type_const == src->type) {
267
                iw[0] |= (0x01 << 3);
268
                iw[1] = src->value & 0x00ff;
269
        } else if (instr_operand_type_reg == src->type) {
270
                iw[1] = src->value & 0x07;
271
                if (0 != (src->flags & INSTR_FLAG_TILDE))
272
                        iw[1] |= (0x01 << 3);
273
        }
274
}
275
 
276
static void _write_logic(unsigned char *iw, instr_opcode_t opcode, const instr_operand_t *dst, const list_t *src_l)
277
{
278
        iw[0] = 0x00;
279
 
280
        switch (opcode) {
281
        case instr_opcode_nand:
282
                iw[0] |= (0x02 << 3);
283
        case instr_opcode_and:
284
                iw[0] |= (0x04 << 5);
285
                break;
286
        case instr_opcode_nor:
287
                iw[0] |= (0x02 << 3);
288
        case instr_opcode_or:
289
                iw[0] |= (0x05 << 5);
290
                break;
291
        case instr_opcode_xnor:
292
                iw[0] |= (0x02 << 3);
293
        case instr_opcode_xor:
294
                iw[0] |= (0x06 << 5);
295
                break;
296
        default:
297
                /* nothing to do */;
298
        }
299
 
300
        iw[0] |= dst->value & 0x07;
301
 
302
        _write_src(iw, dst, src_l);
303
}
304
 
305
static void _gen_code(unsigned char *iw, const instr_t *i)
306
{
307
        switch (i->opcode) {
308
        case instr_opcode_ld:
309
        case instr_opcode_ldi:
310
        case instr_opcode_st:
311
        case instr_opcode_sti:
312
                _write_ldst(iw, i->opcode, &i->dest, _SRC_FIRST(&i->source));
313
                break;
314
        case instr_opcode_add:
315
        case instr_opcode_addi:
316
                _write_add(iw, i->opcode == instr_opcode_addi ? 1 : 0, &i->dest, &i->source);
317
                break;
318
        case instr_opcode_rla:
319
        case instr_opcode_rlc:
320
        case instr_opcode_rra:
321
        case instr_opcode_rrc:
322
                _write_sh(iw, i->opcode, &i->dest, _SRC_FIRST(&i->source));
323
                break;
324
        case instr_opcode_mov:
325
                _write_mov(iw, &i->dest, _SRC_FIRST(&i->source));
326
                break;
327
        case instr_opcode_and:
328
        case instr_opcode_nand:
329
        case instr_opcode_or:
330
        case instr_opcode_nor:
331
        case instr_opcode_xor:
332
        case instr_opcode_xnor:
333
                _write_logic(iw, i->opcode, &i->dest, &i->source);
334
                break;
335
        case instr_opcode_jmp:
336
        case instr_opcode_jc:
337
        case instr_opcode_jz:
338
        case instr_opcode_jnz:
339
                _write_jmp(iw, i->opcode, _SRC_FIRST(&i->source));
340
                break;
341
        }
342
}
343
 
344
void instr_out(const char *filename)
345
{
346
        list_t *head;
347
        int f;
348
 
349
        f = open(filename, O_WRONLY | O_CREAT | O_TRUNC
350
#ifdef __MINGW32__
351
                        | O_BINARY,  S_IRUSR | S_IWUSR
352
#else
353
                        , S_IRUSR | S_IWUSR | S_IRGRP
354
#endif
355
                        );
356
 
357
        if (0 <= f) {
358
                unsigned int addr;
359
 
360
                addr = 0;
361
                for (head = _instr.next; head != &_instr; head = head->next) {
362
                        instr_vliw_t *i = LIST_ENTRY(head, instr_vliw_t, list);
363
                        unsigned char iw[4];
364
                        int err;
365
 
366
                        memset(&iw[0], 0x00, sizeof(iw));
367
 
368
                        while (addr < 0x7ff && addr < i->addr) {
369
                                err = write(f, &iw[0], 4);
370
                                if (err != 4) {
371
                                        fprintf(stderr, "write failed\n");
372
                                        break;
373
                                }
374
 
375
                                addr++;
376
                        }
377
 
378
                        _gen_code(&iw[0], &i->instr[0]);
379
                        _gen_code(&iw[2], &i->instr[1 < i->num ? 1 : 0]);
380
 
381
                        err = write(f, &iw[0], 4);
382
                        if (err != 4) {
383
                                fprintf(stderr, "write failed\n");
384
                                break;
385
                        }
386
 
387
                        addr++;
388
                }
389
 
390
                close(f);
391
        } else
392
                fprintf(stderr, "unable to open output\n");
393
}
394
 
395
int execute(int arg)
396
{
397
        return arg;
398
}
399
 
400
void nextline()
401
{
402
        _linenum++;
403
}
404
 
405
int get_linenum()
406
{
407
        return _linenum;
408
}
409
 
410
int main(int argc, char *argv[])
411
{
412
        _linenum = 0;
413
        _instr_addr = 0;
414
 
415
        if (1 < argc) {
416
                fprintf(stderr, "parse file %s\n", argv[1]);
417
                yyin = fopen(argv[1], "r");
418
        } else
419
                yyin = stdin;
420
 
421
        yyparse();
422
 
423
        instr_out("out.a");
424
 
425
        return 0;
426
}
427
 

powered by: WebSVN 2.1.0

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