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

Subversion Repositories raptor64

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

Go to most recent revision | 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
enum e_sg { noseg, codeseg, dataseg };
39
 
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
{       {"move",op_move}, {"add",op_add}, {"addu", op_addu}, {"mov", op_mov},
49
                {"add",op_addi}, {"sub",op_sub}, {"subu", op_subu},
50
                {"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
                {"bmi", op_bmi},
76
                                {"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
            PutConstant(ap->offset);
193
            fprintf(output,"[%s]",RegMoniker(ap->preg));
194
            break;
195
    case am_indx2:
196
            PutConstant(ap->offset);
197
            fprintf(output,"[%s+%s]",RegMoniker(ap->preg),RegMoniker(ap->sreg));
198
            break;
199
    case am_indx3:
200
            PutConstant(ap->offset);
201
            fprintf(output,"[%s+%s]",RegMoniker(ap->preg),RegMoniker(ap->sreg));
202
            break;
203
    case am_mask:
204
            put_mask(ap->offset);
205
            break;
206
    default:
207
            printf("DIAG - illegal address mode.\n");
208
            break;
209
    }
210
}
211
 
212
/*
213
 *      output a generic instruction.
214
 */
215
void put_code(int op, int len,AMODE *aps,AMODE *apd,AMODE *ap3)
216
{       if( op == op_dc )
217
                {
218
                switch( len )
219
                        {
220
                        case 1: fprintf(output,"\tdb"); break;
221
                        case 2: fprintf(output,"\tdc"); break;
222
                        case 4: fprintf(output,"\tdh"); break;
223
                        case 8: fprintf(output,"\tdw"); break;
224
                        }
225
                }
226
        else
227
                {
228
                        putop(op);
229
                }
230
        if( aps != 0 )
231
        {
232
                fprintf(output,"\t");
233
                                PutAddressMode(aps);
234
                if( apd != 0 )
235
                {
236
                        fprintf(output,",");
237
                        PutAddressMode(apd);
238
                                                if (ap3 != NULL) {
239
                                                        fprintf(output,",");
240
                                                        PutAddressMode(ap3);
241
                                                }
242
                }
243
        }
244
        fprintf(output,"\n");
245
}
246
 
247
/*
248
 *      generate a register mask for restore and save.
249
 */
250
void put_mask(int mask)
251
{
252
        int nn;
253
        int first = 1;
254
 
255
        for (nn = 0; nn < 32; nn++) {
256
                if (mask & (1<<nn)) {
257
                        if (!first)
258
                                fprintf(output,"/");
259
                        fprintf(output,"r%d",nn);
260
                        first = 0;
261
                }
262
        }
263
//      fprintf(output,"#0x%04x",mask);
264
 
265
}
266
 
267
/*
268
 *      generate a register name from a tempref number.
269
 */
270
void putreg(int r)
271
{
272
        fprintf(output, "r%d", r);
273
}
274
 
275
/*
276
 *      generate a named label.
277
 */
278
void gen_strlab(char *s)
279
{       fprintf(output,"%s:\n",s);
280
}
281
 
282
/*
283
 *      output a compiler generated label.
284
 */
285
void put_label(int lab)
286
{
287
        fprintf(output,"L_%d:\n",lab);
288
}
289
 
290
void GenerateByte(int val)
291
{
292
        if( gentype == bytegen && outcol < 60) {
293
        fprintf(output,",%d",val & 0x00ff);
294
        outcol += 4;
295
    }
296
    else {
297
        nl();
298
        fprintf(output,"\tdb\t%d",val & 0x00ff);
299
        gentype = bytegen;
300
        outcol = 19;
301
    }
302
}
303
 
304
void GenerateChar(int val)
305
{
306
        if( gentype == chargen && outcol < 60) {
307
        fprintf(output,",%d",val & 0xffff);
308
        outcol += 6;
309
    }
310
    else {
311
        nl();
312
        fprintf(output,"\tdc\t%d",val & 0xffff);
313
        gentype = chargen;
314
        outcol = 21;
315
    }
316
}
317
 
318
void genhalf(int val)
319
{
320
        if( gentype == bytegen && outcol < 60) {
321
        fprintf(output,",%d",val & 0xffffffff);
322
        outcol += 10;
323
    }
324
    else {
325
        nl();
326
        fprintf(output,"\tdh\t%d",val & 0xffffffff);
327
        gentype = halfgen;
328
        outcol = 25;
329
    }
330
}
331
 
332
void GenerateWord(__int64 val)
333
{
334
        if( gentype == wordgen && outcol < 58) {
335
        fprintf(output,",%I64d",val);
336
        outcol += 18;
337
    }
338
    else {
339
        nl();
340
        fprintf(output,"\tdw\t%I64d",val);
341
        gentype = wordgen;
342
        outcol = 33;
343
    }
344
}
345
 
346
void GenerateLong(__int64 val)
347
{       if( gentype == longgen && outcol < 56) {
348
                fprintf(output,",%I64d",val);
349
                outcol += 10;
350
                }
351
        else    {
352
                nl();
353
                fprintf(output,"\tdw\t%I64d",val);
354
                gentype = longgen;
355
                outcol = 25;
356
                }
357
}
358
 
359
void GenerateReference(SYM *sp,int offset)
360
{
361
        char    sign;
362
    if( offset < 0) {
363
        sign = '-';
364
        offset = -offset;
365
    }
366
    else
367
        sign = '+';
368
    if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
369
        if( sp->storage_class == sc_static)
370
                fprintf(output,",L_%I64d%c%d",sp->value.i,sign,offset);
371
        else
372
                fprintf(output,",%s%c%d",sp->name,sign,offset);
373
        outcol += (11 + strlen(sp->name));
374
    }
375
    else {
376
        nl();
377
        if(sp->storage_class == sc_static)
378
            fprintf(output,"\tdw\tL_%I64d%c%d",sp->value.i,sign,offset);
379
        else
380
            fprintf(output,"\tdw\t%s%c%d",sp->name,sign,offset);
381
        outcol = 26 + strlen(sp->name);
382
        gentype = longgen;
383
    }
384
}
385
 
386
void genstorage(int nbytes)
387
{       nl();
388
        fprintf(output,"\tdcb.b\t%d,0xff\n",nbytes);
389
}
390
 
391
void GenerateLabelReference(int n)
392
{       if( gentype == longgen && outcol < 58) {
393
                fprintf(output,",L_%d",n);
394
                outcol += 6;
395
                }
396
        else    {
397
                nl();
398
                fprintf(output,"\tlong\tL_%d",n);
399
                outcol = 22;
400
                gentype = longgen;
401
                }
402
}
403
 
404
/*
405
 *      make s a string literal and return it's label number.
406
 */
407
int     stringlit(char *s)
408
{
409
        struct slit *lp;
410
 
411
    ++global_flag;          /* always AllocateRegisterVars from global space. */
412
    lp = (struct slit *)xalloc(sizeof(struct slit));
413
    lp->label = nextlabel++;
414
    lp->str = litlate(s);
415
    lp->next = strtab;
416
    strtab = lp;
417
    --global_flag;
418
    return lp->label;
419
}
420
 
421
/*
422
 *      dump the string literal pool.
423
 */
424
void dumplits()
425
{
426
        char            *cp;
427
 
428
    cseg();
429
    nl();
430
        align(8);
431
    nl();
432
        while( strtab != NULL) {
433
            nl();
434
        put_label(strtab->label);
435
        cp = strtab->str;
436
        while(*cp)
437
            GenerateChar(*cp++);
438
        GenerateChar(0);
439
        strtab = strtab->next;
440
    }
441
    nl();
442
}
443
 
444
void nl()
445
{       if(outcol > 0) {
446
                fprintf(output,"\n");
447
                outcol = 0;
448
                gentype = nogen;
449
                }
450
}
451
 
452
void align(int n)
453
{
454
        fprintf(output,"\talign\t%d\n",n);
455
}
456
 
457
void cseg()
458
{
459
        if( curseg != codeseg) {
460
                nl();
461
                fprintf(output,"\tcode\n");
462
                fprintf(output,"\talign\t16\n");
463
                curseg = codeseg;
464
    }
465
}
466
 
467
void dseg()
468
{
469
        if( curseg != dataseg) {
470
                nl();
471
                fprintf(output,"\tdata\n");
472
                fprintf(output,"\talign\t8\n");
473
                curseg = dataseg;
474
    }
475
}
476
 
477


powered by: WebSVN 2.1.0

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