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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [c64/] [source/] [Outcode.c] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 37 robfinch
#include        <stdio.h>
2
#include <string.h>
3
#include        "c.h"
4
#include        "expr.h"
5
#include        "gen.h"
6
#include        "cglbdec.h"
7
 
8
/*
9
 *      68000 C compiler
10
 *
11
 *      Copyright 1984, 1985, 1986 Matthew Brandt.
12
 *  all commercial rights reserved.
13
 *
14
 *      This compiler is intended as an instructive tool for personal use. Any
15
 *      use for profit without the written consent of the author is prohibited.
16
 *
17
 *      This compiler may be distributed freely for non-commercial use as long
18
 *      as this notice stays intact. Please forward any enhancements or questions
19
 *      to:
20
 *
21
 *              Matthew Brandt
22
 *              Box 920337
23
 *              Norcross, Ga 30092
24
 */
25
 
26
/*******************************************************
27
        Modified to support Raptor64 'C64' language
28
        by Robert Finch
29
        robfinch@opencores.org
30
*******************************************************/
31
 
32
void put_mask(int mask);
33
void align(int n);
34
 
35
/*      variable initialization         */
36
 
37
enum e_gt { nogen, bytegen, chargen, halfgen, wordgen, longgen };
38 51 robfinch
//enum e_sg { noseg, codeseg, dataseg, bssseg, idataseg };
39 37 robfinch
 
40
int            gentype = nogen;
41
int            curseg = noseg;
42
int        outcol = 0;
43
 
44
struct oplst {
45
        char    *s;
46
        int     ov;
47
        }       opl[] =
48 51 robfinch
{       {"move",op_move}, {"addu",op_add}, {"addu", op_addu}, {"mov", op_mov},
49
                {"add",op_addi}, {"subu",op_sub}, {"subu", op_subu},
50 37 robfinch
                {"subi",op_subi}, {"and",op_and},
51
                {"sext8",op_sext8}, {"sext16", op_sext16}, {"sext32", op_sext32},
52
                {"subui",op_subui}, {"shru", op_shru}, {"divsi", op_divsi}, {"not", op_not},
53
                {"addui",op_addui}, {"shr", op_shr}, {"dw", op_dw}, {"shl", op_shl}, {"shr", op_shr}, {"shru", op_shru},
54
                {"shli", op_shli}, {"shri", op_shri}, {"shrui", op_shrui},
55
                {"sw", op_sw}, {"lw", op_lw}, {"lh", op_lh}, {"lc", op_lc}, {"lb", op_lb},
56
                {"lm", op_lm}, {"sm",op_sm}, {"sb",op_sb}, {"sc",op_sc}, {"sh",op_sh},
57
                {"call", op_call}, {"ret", op_ret}, {"loop", op_loop}, {"beqi", op_beqi},
58
                {"jal", op_jal}, {"lwr", op_lwr}, {"swc", op_swc}, {"cache",op_cache},
59
                {"or",op_or}, {"ori",op_ori}, {"iret", op_iret}, {"andi", op_andi},
60
                {"xor",op_xor}, {"xori", op_xori}, {"muls",op_muls}, {"mulsi", op_mulsi}, {"mului", op_mului},
61
                {"divs",op_divs}, {"swap",op_swap}, {"mod", op_mod}, {"modu", op_modu},
62
                {"beq",op_beq}, {"bnei", op_bnei}, {"sei", op_sei},
63
                {"bltu", op_bltu}, {"bleu",op_bleu}, {"bgtu",op_bgtu}, {"bgeu", op_bgeu},
64
                {"bhi",op_bhi}, {"bhs",op_bhs}, {"blo",op_blo},
65
                {"bls",op_bls}, {"mulu",op_mulu}, {"divu",op_divu},
66
                {"bne",op_bne}, {"blt",op_blt}, {"ble",op_ble},
67
                {"bgt",op_bgt}, {"bge",op_bge}, {"neg",op_neg}, {"bnr", op_bnr},
68
                {"not",op_not}, {"cmp",op_cmp}, {"ext",op_ext},
69
                {"jmp",op_jmp},
70
                {"lea",op_lea}, {"asr",op_asr},
71
                {"clr",op_clr}, {"link",op_link}, {"unlk",op_unlk},
72
                {"bra",op_bra}, {"pea",op_pea},
73
                                {"cmp",op_cmpi}, {"tst",op_tst},
74
                {"stop", op_stop},
75 51 robfinch
                {"bmi", op_bmi}, {"outb", op_outb}, {"inb", op_inb}, {"inbu", op_inbu},
76 37 robfinch
                                {"dc",op_dc},
77
                {"",op_empty}, {"",op_asm},
78
                {0,0} };
79
 
80
static char *pad(char *op)
81
{
82
        static char buf[20];
83
        int n;
84
 
85
        n = strlen(op);
86
        strncpy(buf,op,20);
87
        if (n < 5) {
88
                strcat(buf, "     ");
89
                buf[5] = '\0';
90
        }
91
        return buf;
92
}
93
 
94
void putop(int op)
95
{
96
        int     i;
97
    i = 0;
98
    while( opl[i].s )
99
    {
100
                if( opl[i].ov == op )
101
                {
102
                        fprintf(output,"\t%s",pad(opl[i].s));
103
                        return;
104
                }
105
                ++i;
106
    }
107
    printf("DIAG - illegal opcode.\n");
108
}
109
 
110
static void PutConstant(ENODE *offset)
111
{
112
        switch( offset->nodetype )
113
        {
114
        case en_autocon:
115
        case en_icon:
116
                        fprintf(output,"%I64d",offset->i);
117
                        break;
118
        case en_labcon:
119
                        fprintf(output,"L_%I64d",offset->i);
120
                        break;
121
        case en_nacon:
122
                        fprintf(output,"%s",offset->sp);
123
                        break;
124
        case en_add:
125
                        PutConstant(offset->p[0]);
126
                        fprintf(output,"+");
127
                        PutConstant(offset->p[1]);
128
                        break;
129
        case en_sub:
130
                        PutConstant(offset->p[0]);
131
                        fprintf(output,"-");
132
                        PutConstant(offset->p[1]);
133
                        break;
134
        case en_uminus:
135
                        fprintf(output,"-");
136
                        PutConstant(offset->p[0]);
137
                        break;
138
        default:
139
                        printf("DIAG - illegal constant node.\n");
140
                        break;
141
        }
142
}
143
 
144
char *RegMoniker(int regno)
145
{
146
        static char buf[4][20];
147
        static int n;
148
 
149
        n = (n + 1) & 3;
150
        switch(regno) {
151
        case 27:        sprintf(&buf[n], "bp"); break;
152
        case 28:        sprintf(&buf[n], "xlr"); break;
153
        case 29:        sprintf(&buf[n], "pc"); break;
154
        case 30:        sprintf(&buf[n], "sp"); break;
155
        case 31:        sprintf(&buf[n], "lr"); break;
156
        default:        sprintf(&buf[n], "r%d", regno); break;
157
        }
158
        return &buf[n];
159
}
160
 
161
void PutAddressMode(AMODE *ap)
162
{
163
        switch( ap->mode )
164
    {
165
    case am_immed:
166
                fprintf(output,"#");
167
    case am_direct:
168
            PutConstant(ap->offset);
169
            break;
170
    case am_reg:
171
                        fprintf(output, "%s", RegMoniker(ap->preg));
172
            break;
173
    case am_ind:
174
                        //if (ap->offset != NULL) {
175
                        //      if (ap->offset->i != 0)
176
                        //              fprintf(output, "%I64d[r%d]", ap->offset->i, ap->preg);
177
                        //      else
178
                        //              fprintf(output,"[r%d]",ap->preg);
179
                        //}
180
                        //else
181
                                fprintf(output,"[%s]",RegMoniker(ap->preg));
182
                        break;
183
    case am_ainc:
184
            fprintf(output,"******[r%d]",ap->preg);
185
                        fprintf(output,"addui\ta%d,a%d,#",ap->preg,ap->preg);
186
            break;
187
    case am_adec:
188
                        fprintf(output,"subui\ta%d,a%d,#",ap->preg,ap->preg);
189
            fprintf(output,"******[a%d]",ap->preg);
190
            break;
191
    case am_indx:
192 51 robfinch
                        if (ap->offset->i != 0)
193
                                PutConstant(ap->offset);
194 37 robfinch
            fprintf(output,"[%s]",RegMoniker(ap->preg));
195
            break;
196
    case am_indx2:
197 51 robfinch
                        if (ap->offset->i != 0)
198
                                PutConstant(ap->offset);
199
                        if (ap->scale==1)
200
                    fprintf(output,"[%s+%s]",RegMoniker(ap->sreg),RegMoniker(ap->preg));
201
                        else
202
                        fprintf(output,"[%s+%s*%d]",RegMoniker(ap->sreg),RegMoniker(ap->preg),ap->scale);
203 37 robfinch
            break;
204
    case am_indx3:
205 51 robfinch
                        if (ap->offset->i != 0)
206
                    PutConstant(ap->offset);
207
            fprintf(output,"[%s+%s]",RegMoniker(ap->sreg),RegMoniker(ap->preg));
208 37 robfinch
            break;
209
    case am_mask:
210
            put_mask(ap->offset);
211
            break;
212
    default:
213
            printf("DIAG - illegal address mode.\n");
214
            break;
215
    }
216
}
217
 
218
/*
219
 *      output a generic instruction.
220
 */
221
void put_code(int op, int len,AMODE *aps,AMODE *apd,AMODE *ap3)
222
{       if( op == op_dc )
223
                {
224
                switch( len )
225
                        {
226
                        case 1: fprintf(output,"\tdb"); break;
227
                        case 2: fprintf(output,"\tdc"); break;
228
                        case 4: fprintf(output,"\tdh"); break;
229
                        case 8: fprintf(output,"\tdw"); break;
230
                        }
231
                }
232
        else
233
                {
234
                        putop(op);
235
                }
236
        if( aps != 0 )
237
        {
238
                fprintf(output,"\t");
239
                                PutAddressMode(aps);
240
                if( apd != 0 )
241
                {
242
                        fprintf(output,",");
243
                        PutAddressMode(apd);
244
                                                if (ap3 != NULL) {
245
                                                        fprintf(output,",");
246
                                                        PutAddressMode(ap3);
247
                                                }
248
                }
249
        }
250
        fprintf(output,"\n");
251
}
252
 
253
/*
254
 *      generate a register mask for restore and save.
255
 */
256
void put_mask(int mask)
257
{
258
        int nn;
259
        int first = 1;
260
 
261
        for (nn = 0; nn < 32; nn++) {
262
                if (mask & (1<<nn)) {
263
                        if (!first)
264
                                fprintf(output,"/");
265
                        fprintf(output,"r%d",nn);
266
                        first = 0;
267
                }
268
        }
269
//      fprintf(output,"#0x%04x",mask);
270
 
271
}
272
 
273
/*
274
 *      generate a register name from a tempref number.
275
 */
276
void putreg(int r)
277
{
278
        fprintf(output, "r%d", r);
279
}
280
 
281
/*
282
 *      generate a named label.
283
 */
284
void gen_strlab(char *s)
285
{       fprintf(output,"%s:\n",s);
286
}
287
 
288
/*
289
 *      output a compiler generated label.
290
 */
291
void put_label(int lab)
292
{
293
        fprintf(output,"L_%d:\n",lab);
294
}
295
 
296
void GenerateByte(int val)
297
{
298
        if( gentype == bytegen && outcol < 60) {
299
        fprintf(output,",%d",val & 0x00ff);
300
        outcol += 4;
301
    }
302
    else {
303
        nl();
304
        fprintf(output,"\tdb\t%d",val & 0x00ff);
305
        gentype = bytegen;
306
        outcol = 19;
307
    }
308
}
309
 
310
void GenerateChar(int val)
311
{
312
        if( gentype == chargen && outcol < 60) {
313
        fprintf(output,",%d",val & 0xffff);
314
        outcol += 6;
315
    }
316
    else {
317
        nl();
318
        fprintf(output,"\tdc\t%d",val & 0xffff);
319
        gentype = chargen;
320
        outcol = 21;
321
    }
322
}
323
 
324
void genhalf(int val)
325
{
326 51 robfinch
        if( gentype == halfgen && outcol < 60) {
327 37 robfinch
        fprintf(output,",%d",val & 0xffffffff);
328
        outcol += 10;
329
    }
330
    else {
331
        nl();
332
        fprintf(output,"\tdh\t%d",val & 0xffffffff);
333
        gentype = halfgen;
334
        outcol = 25;
335
    }
336
}
337
 
338
void GenerateWord(__int64 val)
339
{
340
        if( gentype == wordgen && outcol < 58) {
341
        fprintf(output,",%I64d",val);
342
        outcol += 18;
343
    }
344
    else {
345
        nl();
346 51 robfinch
        fprintf(output,"\tdh\t%I64d",val);
347 37 robfinch
        gentype = wordgen;
348
        outcol = 33;
349
    }
350
}
351
 
352
void GenerateLong(__int64 val)
353 51 robfinch
{
354
        if( gentype == longgen && outcol < 56) {
355 37 robfinch
                fprintf(output,",%I64d",val);
356
                outcol += 10;
357
                }
358
        else    {
359
                nl();
360
                fprintf(output,"\tdw\t%I64d",val);
361
                gentype = longgen;
362
                outcol = 25;
363
                }
364
}
365
 
366
void GenerateReference(SYM *sp,int offset)
367
{
368
        char    sign;
369
    if( offset < 0) {
370
        sign = '-';
371
        offset = -offset;
372
    }
373
    else
374
        sign = '+';
375
    if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
376
        if( sp->storage_class == sc_static)
377
                fprintf(output,",L_%I64d%c%d",sp->value.i,sign,offset);
378
        else
379
                fprintf(output,",%s%c%d",sp->name,sign,offset);
380
        outcol += (11 + strlen(sp->name));
381
    }
382
    else {
383
        nl();
384
        if(sp->storage_class == sc_static)
385
            fprintf(output,"\tdw\tL_%I64d%c%d",sp->value.i,sign,offset);
386
        else
387
            fprintf(output,"\tdw\t%s%c%d",sp->name,sign,offset);
388
        outcol = 26 + strlen(sp->name);
389
        gentype = longgen;
390
    }
391
}
392
 
393
void genstorage(int nbytes)
394
{       nl();
395
        fprintf(output,"\tdcb.b\t%d,0xff\n",nbytes);
396
}
397
 
398
void GenerateLabelReference(int n)
399
{       if( gentype == longgen && outcol < 58) {
400
                fprintf(output,",L_%d",n);
401
                outcol += 6;
402
                }
403
        else    {
404
                nl();
405
                fprintf(output,"\tlong\tL_%d",n);
406
                outcol = 22;
407
                gentype = longgen;
408
                }
409
}
410
 
411
/*
412
 *      make s a string literal and return it's label number.
413
 */
414
int     stringlit(char *s)
415
{
416
        struct slit *lp;
417
 
418 51 robfinch
    ++global_flag;          /* always allocate from global space. */
419 37 robfinch
    lp = (struct slit *)xalloc(sizeof(struct slit));
420
    lp->label = nextlabel++;
421
    lp->str = litlate(s);
422
    lp->next = strtab;
423
    strtab = lp;
424
    --global_flag;
425
    return lp->label;
426
}
427
 
428
/*
429
 *      dump the string literal pool.
430
 */
431
void dumplits()
432
{
433
        char            *cp;
434
 
435
    cseg();
436
    nl();
437
        align(8);
438
    nl();
439
        while( strtab != NULL) {
440
            nl();
441
        put_label(strtab->label);
442
        cp = strtab->str;
443
        while(*cp)
444
            GenerateChar(*cp++);
445
        GenerateChar(0);
446
        strtab = strtab->next;
447
    }
448
    nl();
449
}
450
 
451
void nl()
452
{       if(outcol > 0) {
453
                fprintf(output,"\n");
454
                outcol = 0;
455
                gentype = nogen;
456
                }
457
}
458
 
459
void align(int n)
460
{
461
        fprintf(output,"\talign\t%d\n",n);
462
}
463
 
464
void cseg()
465
{
466
        if( curseg != codeseg) {
467
                nl();
468
                fprintf(output,"\tcode\n");
469
                fprintf(output,"\talign\t16\n");
470
                curseg = codeseg;
471
    }
472
}
473
 
474
void dseg()
475
{
476
        if( curseg != dataseg) {
477
                nl();
478
                fprintf(output,"\tdata\n");
479
                fprintf(output,"\talign\t8\n");
480
                curseg = dataseg;
481
    }
482
}
483
 
484 51 robfinch
void seg(int sg)
485
{
486
        if( curseg != sg) {
487
                nl();
488
                switch(sg) {
489
                case bssseg:
490
                        fprintf(output,"\tbss\n");
491
                        fprintf(output,"\talign\t8\n");
492
                        break;
493
                case dataseg:
494
                        fprintf(output,"\tdata\n");
495
                        fprintf(output,"\talign\t8\n");
496
                        break;
497
                case idataseg:
498
                        fprintf(output,"\tidata\n");
499
                        fprintf(output,"\talign\t8\n");
500
                        break;
501
                case codeseg:
502
                        fprintf(output,"\tcode\n");
503
                        fprintf(output,"\talign\t16\n");
504
                        break;
505
                }
506
                curseg = sg;
507
    }
508
}

powered by: WebSVN 2.1.0

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