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

Subversion Repositories rf6809

[/] [rf6809/] [trunk/] [software/] [vbcc/] [machines/] [hc12/] [machine.c] - Blame information for rev 20

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

Line No. Rev Author Line
1 18 robfinch
/*  Code generator for Motorola 68hc12 microcontrollers.               */
2
 
3
/*TODO:
4
  regs_modified bei struct-copy
5
  savings verfeinern
6
  4-Byte Copy
7
  [static] testen
8
  peephole-Pass um ALLOCREGs zu entfernen
9
  ACC_IND (Achtung?)
10
  struct-copy Problemfälle
11
  banked
12
  bit
13
  long long, float, double, long double
14
 
15
*/
16
 
17
#include "supp.h"
18
#include "vbc.h" /* nicht schoen, aber ... */
19
 
20
static char FILE_[]=__FILE__;
21
 
22
#include "dwarf2.c"
23
 
24
/*  Public data that MUST be there.                             */
25
 
26
/* Name and copyright. */
27
char cg_copyright[]="vbcc code-generator for 6809/6803/68hc12 V0.2 (c) in 2000-2022 by Volker Barthelmann";
28
 
29
/*  Commandline-flags the code-generator accepts                */
30
int g_flags[MAXGF]={VALFLAG,VALFLAG,0,0,
31
                    0,0,0,0,
32
                    0,0};
33
char *g_flags_name[MAXGF]={"cpu","fpu","no-delayed-popping","const-in-data",
34
                           "merge-constants","no-peephole","mem-cse","acc-glob",
35
                           "pcrel","drel","no-char-addi2p","nodx","nou"};
36
union ppi g_flags_val[MAXGF];
37
 
38
/* Typenames (needed because of HAVE_EXT_TYPES). */
39
char *typname[]={"strange","bit","char","short","int","long","long long",
40
                 "float","double","long double","void",
41
                 "near-pointer","far-pointer","huge-pointer",
42
                 "array","struct","union","enum","function"};
43
 
44
int bitsperbyte = 8;
45
int bytemask = 0xff;
46
int dbl_bytemask = 0xffff;
47
 
48
/*  Alignment-requirements for all types in bytes.              */
49
zmax align[MAX_TYPE+1];
50
 
51
/*  Alignment that is sufficient for every object.              */
52
zmax maxalign;
53
 
54
/*  CHAR_BIT of the target machine.                             */
55
zmax char_bit;
56
 
57
/*  Sizes of all elementary types in bytes.                     */
58
zmax sizetab[MAX_TYPE+1];
59
 
60
/*  Minimum and Maximum values each type can have.              */
61
/*  Must be initialized in init_cg().                           */
62
zmax t_min[MAX_TYPE+1];
63
zumax t_max[MAX_TYPE+1];
64
zumax tu_max[MAX_TYPE+1];
65
 
66
/*  Names of all registers.                                     */
67
char *regnames[]={"noreg","d","x","y","sp","u","d/x"};
68
 
69
/*  The Size of each register in bytes.                         */
70
zmax regsize[MAXR+1];
71
 
72
/*  Type which can store each register. */
73
struct Typ *regtype[MAXR+1];
74
 
75
/*  regsa[reg]!=0 if a certain register is allocated and should */
76
/*  not be used by the compiler pass.                           */
77
int regsa[MAXR+1];
78
 
79
/*  Specifies which registers may be scratched by functions.    */
80
int regscratch[MAXR+1]={0,1,1,0,1,0};
81
 
82
int reg_prio[MAXR+1]={0,0,1,1,0,0};
83
 
84
struct reg_handle empty_reg_handle={0};
85
 
86
/* Names of target-specific variable attributes.                */
87
char *g_attr_name[]={"__interrupt","__dpage","__far",0};
88
#define INTERRUPT 1
89
#define DPAGE     2
90
#define FAR                             4
91
 
92
int MINADDI2P=CHAR;
93
 
94
/****************************************/
95
/*  Some private data and functions.    */
96
/****************************************/
97
 
98
static long malign[MAX_TYPE+1]=  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
99
static long msizetab[MAX_TYPE+1]={0,1,1,2,2,4,4,4,4,4,0,2,4,4,0,0,0,2,0};
100
 
101
struct Typ ityp={SHORT},ltyp={LONG};
102
 
103
#define DATA 0
104
#define BSS 1
105
#define CODE 2
106
#define RODATA 3
107
#define SPECIAL 4
108
 
109
static int section=-1,newobj,scnt,pushed_acc;
110
static char *codename="\t.text\n",
111
            *dataname="\t.data\n",
112
            *bssname="\t.section\t.bss\n",
113
            *rodataname="\t.section\t.rodata\n";
114
 
115
#define IMM_IND  1
116
#define VAR_IND  2
117
#define POST_INC 3
118
#define POST_DEC 4
119
#define PRE_INC  5
120
#define PRE_DEC  6
121
#define ACC_IND  7
122
#define KONSTINC 8
123
 
124
/* (user)stack-pointer, pointer-tmp, int-tmp; reserved for compiler */
125
static int acc=1,ix=2,iy=3,sp=4,iu=5,dx=6;
126
static void pr(FILE *,struct IC *);
127
static void function_top(FILE *,struct Var *,long);
128
static void function_bottom(FILE *f,struct Var *,long);
129
 
130
static char *marray[]={"__section(x,y)=__vattr(\"section(\"#x\",\"#y\")\")",
131
                       "__HC12__",
132
                       "__SIZE_T_INT=1",
133
                       "__direct=__vattr(\"section(\\\"dpage\\\")\")",
134
                       0};
135
 
136
#define isreg(x) ((p->x.flags&(REG|DREFOBJ))==REG)
137
#define isconst(x) ((p->x.flags&(KONST|DREFOBJ))==KONST)
138
 
139
static long loff,roff,stackoffset,notpopped,dontpop,maxpushed,stack;
140
 
141
static char *x_t[]={"?","","b","","","","","","","","","","","","","",""};
142
static char *ccs[]={"eq","ne","lt","ge","le","gt"};
143
static char *uccs[]={"eq","ne","lo","hs","ls","hi"};
144
static char *logicals[]={"ora","eor","and"};
145
static char *dct[]={"",".bit",".byte",".2byte",".2byte",".4byte",".8byte",".4byte",".8byte",".8byte",
146
                    "(void)",".2byte",".34byte",".34byte"};
147
static char *idprefix="",*labprefix=".l";
148
static int exit_label,have_frame;
149
static char *ret;
150
static int stackchecklabel;
151
static int frame_used,stack_valid;
152
static int CPU=6812;
153
static int pcrel,drel;
154
static int skip_rel;
155
static char *jsrinst="jsr";
156
static char *jmpinst="jmp";
157
static int nodx,nou;
158
int switchsubs;
159
 
160
static int cc_t;
161
static struct obj *cc;
162
 
163
static struct obj mobj;
164
 
165
#define STR_NEAR "near"
166
#define STR_FAR "far"
167
#define STR_HUGE "huge"
168
#define STR_BADDR "baddr"
169
 
170
#define ISNULL() (zmeqto(vmax,l2zm(0L))&&zumeqto(vumax,ul2zum(0UL))&&zldeqto(vldouble,d2zld(0.0)))
171
#define ISLWORD(t) ((t&NQ)==LONG||(t&NQ)==FPOINTER||(t&NQ)==HPOINTER||(t&NQ)==FLOAT)
172
#define ISHWORD(t) ((t&NQ)==INT||(t&NQ)==SHORT||(t&NQ)==NPOINTER)
173
#define ISCHWORD(t) ((t&NQ)==CHAR||ISHWORD(t))
174
#define ISSTATIC(v) ((v)->storage_class==EXTERN||(v)->storage_class==STATIC)
175
#define ISBADDR(v) ((v)->vtyp->attr&&strstr(STR_BADDR,(v)->vtyp->attr))
176
/*FIXME*/
177
#define ISFAR(v) ((v)->vtyp->attr&&(strstr(STR_FAR,(v)->vtyp->attr)||strstr(STR_HUGE,(v)->vtyp->attr)))
178
 
179
#define ISACC(x) ((x)==acc)
180
#define ISX(x) ((x)==ix)
181
#define ISY(x) ((x)==iy)
182
#define ISU(x) ((x)==iu)
183
#define ISIDX(x) (ISX(x)||ISY(x)||(ISU(x)&&CPU!=6812))
184
#define ISRACC(x) (isreg(x)&&ISACC(p->x.reg))
185
#define ISRX(x) (isreg(x)&&ISX(p->x.reg))
186
#define ISRY(x) (isreg(x)&&ISY(p->x.reg))
187
#define ISRU(x) (isreg(x)&&ISU(p->x.reg))
188
#define ISRIDX(x) (isreg(x)&&ISIDX(p->x.reg))
189
 
190
#define CPUOPT ((g_flags[0]&USEDFLAG)?g_flags_val[0].l:6812)
191
 
192
#define SPUSH(x) (CPU==6812?"\tpsh" x "\n":"\tpshs\t" x "\n")
193
#define SPUSHD   (CPU==6812?"\tpshd\n":"\tpshs\tb,a\n")
194
#define SPULL(x) (CPU==6812?"\tpul" x "\n":"\tpuls\t" x "\n")
195
#define SPULLD   (CPU==6812?"\tpuld\n":"\tpuls\ta,b\n")
196
#define SCMP(x)  (CPU==6812?"\tcp" x "\t":"\tcmp" x "\t")
197
#define SEX      (CPU==6812?"\tsex\tb,d\n":"\tsex\n")
198
 
199
#define SGN16(x) (zm2l(zi2zm(zm2zi(l2zm((long)(x))))))
200
 
201
enum peepf { NEEDSAME = 1, REMOVE1ST = 2, ALLOWSFX = 4};
202
struct peeps {char *s1,*s2,*r;enum peepf flags;};
203
 
204
static int check_sfx(char *s)
205
{
206
  if(!*s) return 0;
207
  s+=strlen(s)-1;
208
  if(*s=='+'||*s=='-') return 1;
209
  if(*s!='s'&&*s!='x'&&*s!='y'&&*s!='u') return 0;
210
  s--;
211
  if(*s!=',') return 0;
212
  s--;
213
  if(*s=='+'||*s=='-') return 1;
214
  return 0;
215
}
216
 
217
static int setszflag(char *op,char r)
218
{
219
  static char *zb[]={"adcb","addb","andb","aslb","asrb","clrb","comb","decb","eorb","incb",
220
                "ldab","ldb","lslb","lsrb","negb","orb","orab","rolb","rorb","sbcb",
221
                "stb","stab","subb","tstb"};
222
  static char *zd[]={"addd","ldd","sex","std","subd"};
223
 
224
  int i;
225
 
226
  if(r=='b'){
227
    for(i=0;i<sizeof(zb)/sizeof(*zb);i++)
228
      if(!strcmp(op,zb[i]))
229
        return 1;
230
  }
231
  if(r=='d'){
232
    for(i=0;i<sizeof(zd)/sizeof(*zd);i++)
233
      if(!strcmp(op,zd[i]))
234
        return 1;
235
  }
236
  if(r=='x'&&(!strcmp(op,"leax")||!strcmp(op,"ldx"))) return 1;
237
  if(r=='y'&&(!strcmp(op,"leay")||!strcmp(op,"ldy"))) return 1;
238
  if(CPU==6812){
239
    if(r=='x'&&(!strcmp(op,"dex")||!strcmp(op,"inx"))) return 1;
240
    if(r=='y'&&(!strcmp(op,"dey")||!strcmp(op,"iny"))) return 1;
241
  }
242
  return 0;
243
}
244
 
245
int emit_peephole(void)
246
{
247
  int entries,i,j,v1,v2;
248
  char *asmline[EMIT_BUF_DEPTH];
249
  char buf1[1024],buf2[1024];
250
  char op1[8],op2[8];
251
 
252
 
253
  /* TODO: adapt better */
254
  static struct peeps elim[]={
255
    "lda","sta",0,NEEDSAME,
256
    "ldb","stb",0,NEEDSAME,
257
    "ldaa","staa",0,NEEDSAME,
258
    "ldab","stab",0,NEEDSAME,
259
    "ldd","std",0,NEEDSAME,
260
    "ldx","stx",0,NEEDSAME,
261
    "ldy","sty",0,NEEDSAME,
262
    "ldu","stu",0,NEEDSAME,
263
    "sta","sta",0,NEEDSAME,
264
    "stb","stb",0,NEEDSAME,
265
    "staa","staa",0,NEEDSAME,
266
    "stab","stab",0,NEEDSAME,
267
    "std","std",0,NEEDSAME,
268
    "stx","stx",0,NEEDSAME,
269
    "sty","sty",0,NEEDSAME,
270
    "stu","stu",0,NEEDSAME,
271
    "sta","lda",0,NEEDSAME,
272
    "stb","ldb",0,NEEDSAME,
273
    "staa","ldaa",0,NEEDSAME,
274
    "stab","ldab",0,NEEDSAME,
275
    "std","ldd",0,NEEDSAME,
276
    "stx","ldx",0,NEEDSAME,
277
    "sty","ldy",0,NEEDSAME,
278
    "stu","ldu",0,NEEDSAME,
279
#if 0
280
    "lda","lda",0,REMOVE1ST,
281
    "ldaa","ldaa",0,REMOVE1ST,
282
    "ldab","ldab",0,REMOVE1ST,
283
    "ldb","ldb",0,REMOVE1ST,
284
    "ldd","ldd",0,REMOVE1ST,
285
    "ldx","ldx",0,REMOVE1ST,
286
    "ldy","ldy",0,REMOVE1ST,
287
    "ldu","ldu",0,REMOVE1ST,
288
    "lda","pla",0,REMOVE1ST,
289
    "lda","txa",0,REMOVE1ST,
290
    "lda","tya",0,REMOVE1ST,
291
    "ldx","tax",0,REMOVE1ST,
292
    "ldy","tay",0,REMOVE1ST,
293
    "tay","ldy",0,REMOVE1ST,
294
    "tax","ldx",0,REMOVE1ST,
295
    "txa","lda",0,REMOVE1ST,
296
    "tya","lda",0,REMOVE1ST,
297
#endif
298
  };
299
 
300
 
301
  i=emit_l;
302
  if(emit_f==0)
303
    entries=i-emit_f+1;
304
  else
305
    entries=EMIT_BUF_DEPTH;
306
  asmline[0]=emit_buffer[i];
307
  if(sscanf(asmline[0]," %6s %999s",op1,buf1)==2&&!strcmp(op1,"cmpb")&&!strcmp(buf1,"#0"))
308
    strcpy(asmline[0],"\ttstb\n");
309
  if(sscanf(asmline[0]," %6s %999s",op1,buf1)==2&&!strcmp(op1,"cmpd")&&!strcmp(buf1,"#0"))
310
    strcpy(asmline[0],"\tsubd\t#0\n");
311
 
312
  if(entries>=2){
313
    i--;
314
    if(i<0) i=EMIT_BUF_DEPTH-1;
315
    asmline[1]=emit_buffer[i];
316
 
317
    for(j=0;j<sizeof(elim)/sizeof(elim[0]);j++){
318
      if(elim[j].flags&NEEDSAME){
319
        if(sscanf(asmline[0]," %6s %999s",op2,buf2)==2&&
320
           sscanf(asmline[1]," %6s %999s",op1,buf1)==2&&
321
           !strcmp(op1,elim[j].s1)&&!strcmp(op2,elim[j].s2)&&
322
           !strcmp(buf1,buf2)){
323
          if(!check_sfx(buf1)&&!check_sfx(buf2)){
324
            if(elim[j].r){
325
              strcpy(asmline[0],elim[j].r);
326
            }else{
327
              if(elim[j].flags&REMOVE1ST)
328
                strcpy(asmline[1],asmline[0]);
329
              remove_asm();
330
            }
331
            return 1;
332
          }
333
        }
334
      }else{
335
        *buf1=0;*buf2=0;
336
        if(sscanf(asmline[1]," %6s %999s",op1,buf1)>=1&&
337
           sscanf(asmline[0]," %6s %999s",op2,buf2)>=1&&
338
           !strcmp(op1,elim[j].s1)&&!strcmp(op2,elim[j].s2)){
339
          if((elim[j].flags&ALLOWSFX)||(!check_sfx(buf1)&&!check_sfx(buf2))){
340
            if(elim[j].flags&REMOVE1ST)
341
              strcpy(asmline[1],asmline[0]);
342
            remove_asm();
343
            return 1;
344
          }
345
        }
346
      }
347
    }
348
 
349
    if(!strcmp(asmline[0],"\trts\n")&&sscanf(asmline[1]," %6s %999s",op1,buf1)==2&&!strcmp(op1,"puls")){
350
      sprintf(asmline[1]+strlen(asmline[1])-1,",pc\n");
351
      remove_asm();
352
      return 1;
353
    }
354
 
355
    if(!strcmp(asmline[0],"\tstb\t0,s\n")&&!strcmp(asmline[1],"\tleas\t-1,s\n")){
356
      strcpy(asmline[1],"\tpshs\tb\n");
357
      remove_asm();
358
      return 1;
359
    }
360
 
361
    if(!strcmp(asmline[0],"\tstd\t0,s\n")&&!strcmp(asmline[1],"\tleas\t-2,s\n")){
362
      strcpy(asmline[1],"\tpshs\tb,a\n");
363
      remove_asm();
364
      return 1;
365
    }
366
 
367
    if(!strcmp(asmline[0],"\tldb\t0,s\n")&&!strcmp(asmline[1],"\tpshs\tb\n")){
368
      remove_asm();
369
      return 1;
370
    }
371
 
372
    if(!strcmp(asmline[0],"\tldd\t0,s\n")&&!strcmp(asmline[1],"\tpshs\tb,a\n")){
373
      remove_asm();
374
      return 1;
375
    }
376
 
377
    if(!strcmp(asmline[0],"\tpshs\tb,a\n")&&!strcmp(asmline[1],"\tpuls\ta,b\n")){
378
      strcpy(asmline[1],"\tldd\t0,s\n");
379
      remove_asm();
380
      return 1;
381
    }
382
 
383
    if(sscanf(asmline[1]," ldd %999s",op1)>=1&&sscanf(asmline[0]," ldd %999s",op2)>=1){
384
      if(!((op2[0]=='a'||op2[0]=='b'||op2[0]=='d')&&op2[1]==',')){
385
        strcpy(asmline[1],asmline[0]);
386
        remove_asm();
387
        return 1;
388
      }
389
    }
390
 
391
    if(!strcmp(asmline[0],"\ttfr\tx,d\n")&&!strcmp(asmline[1],"\ttfr\td,x\n")){
392
      remove_asm();
393
      return 1;
394
    }
395
    if(!strcmp(asmline[0],"\ttfr\ty,d\n")&&!strcmp(asmline[1],"\ttfr\td,y\n")){
396
      remove_asm();
397
      return 1;
398
    }
399
    if(!strcmp(asmline[0],"\tstd\t0,sp\n")&&!strcmp(asmline[1],"\tpshd\n")){
400
      remove_asm();
401
      return 1;
402
    }
403
    if(!strcmp(asmline[0],"\tldd\t0,sp\n")&&!strcmp(asmline[1],"\tpshd\n")){
404
      remove_asm();
405
      return 1;
406
    }
407
 
408
    if(sscanf(asmline[0]," leas %d,s",&v1)==1&&sscanf(asmline[1]," leas %d,s",&v2)==1){
409
      sprintf(asmline[1],"\tleas\t%ld,s\n",SGN16(v1+v2));
410
      remove_asm();
411
      return 1;
412
    }
413
 
414
    if(CPU!=6812&&sscanf(asmline[0]," tfr %c,%c",buf1,buf2)==2){
415
      if((*buf1=='x'||*buf1=='y'||*buf1=='u'||*buf1=='s')&&
416
         (*buf2=='x'||*buf2=='y'||*buf2=='u'||*buf2=='s')){
417
        sprintf(asmline[0],"\tlea%c\t,%c\n",*buf2,*buf1);
418
      }
419
    }
420
    if(CPU==6812&&(!strcmp(asmline[1],"\tdex\n")||!strcmp(asmline[1],"\tdey\n")||!strcmp(asmline[1],"\tsubd\t#1\n"))&&
421
       (!strncmp(asmline[0],"\tbne\t",5)||!strncmp(asmline[0],"\tbeq\t",5))){
422
      char r=asmline[1][3];
423
      if(r=='b') r='d';
424
      strcpy(asmline[1],"\td");
425
      strncpy(asmline[1]+2,asmline[0]+1,4);
426
      asmline[1][6]=r;asmline[1][7]=',';
427
      strcpy(asmline[1]+8,asmline[0]+5);
428
      remove_asm();
429
      return 1;
430
    }
431
    if(CPU==6812&&(!strcmp(asmline[1],"\tinx\n")||!strcmp(asmline[1],"\tiny\n")||!strcmp(asmline[1],"\taddd\t#1\n"))&&
432
       (!strncmp(asmline[0],"\tbne\t",5)||!strncmp(asmline[0],"\tbeq\t",5))){
433
      char r=asmline[1][3];
434
      strcpy(asmline[1],"\ti");
435
      strncpy(asmline[1]+2,asmline[0]+1,4);
436
      asmline[1][6]=r;asmline[1][7]=',';
437
      strcpy(asmline[1]+8,asmline[0]+5);
438
      remove_asm();
439
      return 1;
440
    }
441
  }
442
  if(entries>=3){
443
    i--;
444
    if(i<0) i=EMIT_BUF_DEPTH-1;
445
    asmline[2]=emit_buffer[i];
446
    if(sscanf(asmline[0]," %6s %999s",op1,buf1)==2){
447
      if(!strcmp(op1,"beq")||!strcmp(op1,"bne")){
448
        if(!strcmp(asmline[1],"\ttstb\n")||!strcmp(asmline[1],"\tcpb\t#0\n")){
449
          if(sscanf(asmline[2]," %6s %999s",op2,buf2)>=1&&
450
             setszflag(op2,'b')){
451
            strcpy(asmline[1],asmline[0]);
452
            remove_asm();
453
            return 1;
454
          }
455
        }
456
        if(sscanf(asmline[1]," %6s %999s",op2,buf2)==2&&
457
           (!strcmp(op2,"subd")||!strcmp(op2,"cpd"))&&!strcmp(buf2,"#0")){
458
          if(sscanf(asmline[2]," %6s %999s",op2,buf2)>=1&&
459
             setszflag(op2,'d')){
460
            strcpy(asmline[1],asmline[0]);
461
            remove_asm();
462
            return 1;
463
          }
464
        }
465
        if(sscanf(asmline[1]," %6s %999s",op2,buf2)==2&&
466
           !strcmp(op2,(CPU==6812)?"cpx":"cmpx")&&!strcmp(buf2,"#0")){
467
          if(sscanf(asmline[2]," %6s %999s",op2,buf2)>=1&&
468
             setszflag(op2,'x')){
469
            strcpy(asmline[1],asmline[0]);
470
            remove_asm();
471
            return 1;
472
          }
473
        }
474
        if(sscanf(asmline[1]," %6s %999s",op2,buf2)==2&&
475
           !strcmp(op2,(CPU==6812)?"cpy":"cmpy")&&!strcmp(buf2,"#0")){
476
          if(sscanf(asmline[2]," %6s %999s",op2,buf2)>=1&&
477
             setszflag(op2,'y')){
478
            strcpy(asmline[1],asmline[0]);
479
            remove_asm();
480
            return 1;
481
          }
482
        }
483
      }
484
    }
485
  }
486
  return 0;
487
}
488
 
489
static int special_section(FILE *f,struct Var *v)
490
{
491
  char *sec;
492
  if(v->tattr&DPAGE){
493
    emit(f,"\t.section\t.dpage\n");
494
  }else{
495
    if(!v->vattr) return 0;
496
    sec=strstr(v->vattr,"section(");
497
    if(!sec) return 0;
498
    sec+=strlen("section(");
499
    emit(f,"\t.section\t");
500
    while(*sec&&*sec!=')') emit_char(f,*sec++);
501
    emit(f,"\n");
502
  }
503
  if(f) section=SPECIAL;
504
  return 1;
505
}
506
 
507
static struct fpconstlist {
508
    struct fpconstlist *next;
509
    int label,typ;
510
    union atyps val;
511
} *firstfpc;
512
 
513
static int addfpconst(struct obj *o,int t)
514
{
515
  struct fpconstlist *p=firstfpc;
516
  t&=NQ;
517
  if(g_flags[4]&USEDFLAG){
518
    for(p=firstfpc;p;p=p->next){
519
      if(t==p->typ){
520
        eval_const(&p->val,t);
521
        if(t==FLOAT&&zldeqto(vldouble,zf2zld(o->val.vfloat))) return p->label;
522
        if(t==DOUBLE&&zldeqto(vldouble,zd2zld(o->val.vdouble))) return p->label;
523
        if(t==LDOUBLE&&zldeqto(vldouble,o->val.vldouble)) return p->label;
524
      }
525
    }
526
  }
527
  p=mymalloc(sizeof(struct fpconstlist));
528
  p->next=firstfpc;
529
  p->label=++label;
530
  p->typ=t;
531
  p->val=o->val;
532
  firstfpc=p;
533
  return p->label;
534
}
535
 
536
int pointer_type(struct Typ *p)
537
{
538
  if(!p) ierror(0);
539
  while((p->flags&NQ)==ARRAY) p=p->next;
540
  if((p->flags&NQ)==FUNKT) {
541
        if(p->attr)
542
        if(strstr(p->attr,STR_FAR)) return FPOINTER;
543
        if (p->flags&FAR)
544
                return FPOINTER;
545
        return NPOINTER; /*FIXME: banked*/
546
  }
547
  if(p->attr){
548
    if(strstr(p->attr,STR_HUGE)) return HPOINTER;
549
    if(strstr(p->attr,STR_FAR)) return FPOINTER;
550
    if(strstr(p->attr,STR_NEAR)) return NPOINTER;
551
  }
552
  /*FIXME*/
553
  return NPOINTER;
554
}
555
static long voff(struct obj *p)
556
{
557
  if(zm2l(p->v->offset)<0)
558
    return loff-zm2l(p->v->offset)+zm2l(p->val.vmax)-stackoffset+1;
559
  else
560
    return zm2l(p->v->offset)+zm2l(p->val.vmax)-stackoffset;
561
}
562
 
563
static void emit_obj(FILE *f,struct obj *p,int t)
564
/*  Gibt Objekt auf Bildschirm aus                      */
565
{
566
  if(p->am){
567
    int flags=p->am->flags;
568
    if(flags==ACC_IND){
569
      emit(f,"%s,%s",regnames[acc],regnames[p->am->base]);
570
      return;
571
    }
572
    if(flags==KONSTINC){
573
      eval_const(&p->val,p->am->base);
574
      if((t&NQ)==CHAR){
575
        vumax=zumrshift(vumax,bitsperbyte*3-bitsperbyte*p->am->offset);
576
        vumax=zumand(vumax,ul2zum(tu_max[CHAR]));
577
      }else{
578
        vumax=zumrshift(vumax,bitsperbyte*2-bitsperbyte*p->am->offset);
579
        vumax=zumand(vumax,ul2zum(tu_max[SHORT]));
580
      }
581
      emit(f,"#%lu",zum2ul(vumax));
582
      return;
583
    }
584
    if(flags<POST_INC||flags>PRE_DEC||CPU==6812)
585
      emit(f,"%ld",p->am->offset&tu_max[SHORT]);
586
    if(p->am->v){
587
      if(p->am->v->storage_class==STATIC)
588
        emit(f,"+%s%ld",labprefix,zm2l(p->am->v->offset));
589
      else
590
        emit(f,"+(%s%s)",idprefix,p->am->v->identifier);
591
    }
592
    emit(f,",");
593
    if(flags==PRE_INC){
594
      emit(f,"+");
595
      if(p->am->offset==2&&CPU!=6812) emit(f,"+");
596
    }else if(flags==PRE_DEC){
597
      emit(f,"-");
598
      if(p->am->offset==2&&CPU!=6812) emit(f,"-");
599
    }
600
    emit(f,"%s",regnames[p->am->base]);
601
    if(flags==POST_INC){
602
      emit(f,"+");
603
      if(p->am->offset==2&&CPU!=6812) emit(f,"+");
604
    }else if(flags==POST_DEC){
605
      emit(f,"-");
606
      if(p->am->offset==2&&CPU!=6812) emit(f,"-");
607
    }
608
    return;
609
  }
610
  if((p->flags&(KONST|DREFOBJ))==(KONST|DREFOBJ)){
611
    emitval(f,&p->val,p->dtyp&NU);
612
    return;
613
  }
614
  if(p->flags&VARADR) emit(f,"#");
615
  if((p->flags&(DREFOBJ|REG))==(DREFOBJ|REG)) emit(f,"0,");
616
  if((p->flags&(DREFOBJ|REG))==DREFOBJ) emit(f,"[");
617
  if((p->flags&(VAR|REG))==VAR){
618
    if(p->v->storage_class==AUTO||p->v->storage_class==REGISTER){
619
      emit(f,"%ld,%s",voff(p),regnames[sp]);
620
    }else{
621
      if(!zmeqto(l2zm(0L),p->val.vmax)){
622
        emit(f,"%ld",zm2l(zi2zm(zm2zi(p->val.vmax))));
623
        emit(f,"+");
624
      }
625
      if(p->v->storage_class==STATIC){
626
        emit(f,"%s%ld",labprefix,zm2l(p->v->offset));
627
      }else{
628
        emit(f,"(%s%s)",idprefix,p->v->identifier);
629
      }
630
      if(pcrel&&!(p->flags&VARADR)&&ISFUNC(p->v->vtyp->flags))
631
        emit(f,",pc");
632
      if(drel&&!(p->flags&VARADR)&&!ISFUNC(p->v->vtyp->flags)){
633
        if(CPU==6812) ierror(0);
634
        emit(f,",%s",regnames[iu]);
635
      }
636
    }
637
  }
638
  if(p->flags&REG){
639
    if(ISACC(p->reg)&&(t&NQ)==CHAR)
640
      emit(f,"b");
641
    else
642
      emit(f,"%s",regnames[p->reg]);
643
  }
644
  if(p->flags&KONST){
645
    if(ISFLOAT(t)){
646
      emit(f,"%s%d",labprefix,addfpconst(p,t));
647
    }else{
648
      emit(f,"#");emitval(f,&p->val,t&NU);
649
    }
650
  }
651
  if((p->flags&(DREFOBJ|REG))==DREFOBJ){
652
    if(p->v->storage_class==EXTERN||p->v->storage_class==STATIC){
653
      if(is_const(p->v->vtyp)){
654
        if(!pcrel&&CPU==6812) emit(f,",pc");
655
      }else{
656
        if(!drel&&CPU==6812) emit(f,",pc");
657
      }
658
    }
659
    emit(f,"]");
660
  }
661
}
662
 
663
static void dwarf2_print_frame_location(FILE *f,struct Var *v)
664
{
665
  /*FIXME: needs a location list and correct register translation */
666
  struct obj o;
667
  o.flags=REG;
668
  o.reg=sp;
669
  o.val.vmax=l2zm(0L);
670
  o.v=0;
671
  dwarf2_print_location(f,&o);
672
}
673
static int dwarf2_regnumber(int r)
674
{
675
  /*FIXME: always returns D as accumulator, even if byte size */
676
  static int dwarf_regs[MAXR+1]={-1,3,7,8,15};
677
  return dwarf_regs[r];
678
}
679
static zmax dwarf2_fboffset(struct Var *v)
680
{
681
  /*FIXME*/
682
  if(!v||(v->storage_class!=AUTO&&v->storage_class!=REGISTER)) ierror(0);
683
  if(!zmleq(l2zm(0L),v->offset))
684
    return l2zm((long)(loff-zm2l(v->offset)));
685
  else
686
    return v->offset;
687
}
688
 
689
/* test operand for mov instruction */
690
static int mov_op(struct obj *o)
691
{
692
  long off;
693
  if(CPU!=6812) return 0;
694
  if(o->am){
695
    int f=o->am->flags;
696
    if(f==POST_INC||f==PRE_INC||f==POST_DEC||f==PRE_DEC||f==ACC_IND)
697
      return 1;
698
    if(f==IMM_IND){
699
      if(o->am->v) return 0;
700
      off=o->am->offset;
701
      if(off>=-256&&off<=255)
702
        return 1;
703
      else
704
        return 0;
705
    }
706
    ierror(0);
707
  }
708
  if(o->flags&(KONST|VARADR)) return 1;
709
  if((o->flags&(REG|DREFOBJ))==(REG|DREFOBJ)) return 1;
710
  if((o->flags&(VAR|REG|DREFOBJ))==VAR){
711
    if(o->v->storage_class==STATIC||o->v->storage_class==EXTERN)
712
      return 1;
713
    off=voff(o);
714
    if(off>=-256&&off<=255)
715
      return 1;
716
    else
717
      return 0;
718
  }
719
  return 0;
720
}
721
 
722
/* add an offset to an object describing a memory address */
723
static void inc_addr(struct obj *o,long val,int t)
724
{
725
  if(o->am){
726
    int f=o->am->flags;
727
    if(f==IMM_IND||f==KONSTINC)
728
      o->am->offset+=val;
729
    else if(f==POST_INC||f==POST_DEC||f==PRE_INC||f==PRE_DEC){
730
      struct AddressingMode *old=o->am;
731
      o->am=mymalloc(sizeof(*o->am));
732
      o->am->flags=IMM_IND;
733
      o->am->base=old->base;
734
      o->am->v=0;
735
      if(f==POST_DEC) o->am->offset=old->offset-val;
736
      else if(f==POST_INC) o->am->offset=-old->offset+val;
737
      else if(f==PRE_DEC) o->am->offset=val;
738
      else o->am->offset=-val;
739
    }else
740
      ierror(0);
741
  }else if(o->flags&DREFOBJ){
742
    struct AddressingMode *am;
743
    o->am=am=mymalloc(sizeof(*am));
744
    am->flags=IMM_IND;
745
    if(!o->reg) ierror(0);
746
    am->base=o->reg;
747
    am->offset=zm2l(val);
748
    am->v=0;
749
  }else if(o->flags&KONST){
750
    struct AddressingMode *am;
751
    if(o->am) ierror(0);
752
    o->am=am=mymalloc(sizeof(*am));
753
    am->flags=KONSTINC;
754
    am->offset=zm2l(val);
755
    am->base=t;
756
  }else{
757
    o->val.vmax=zmadd(o->val.vmax,val);
758
  }
759
}
760
 
761
/* pushed on the stack by a callee, no pop needed */
762
static void callee_push(long l)
763
{
764
  if(l-stackoffset>stack)
765
    stack=l-stackoffset;
766
}
767
static void push(long l)
768
{
769
  stackoffset-=l;
770
  if(stackoffset<maxpushed) maxpushed=stackoffset;
771
  if(-maxpushed>stack) stack=-maxpushed;
772
}
773
static void pop(long l)
774
{
775
  stackoffset+=l;
776
}
777
static void gen_pop(FILE *f,long l)
778
{
779
  if(l==0) return;
780
  if(l==1&&CPU==6812){
781
    emit(f,"\tins\n");
782
#if 0 /* might clobber return register */
783
  }else if(l==2&&!regs[acc]){
784
    emit(f,SPULLD);
785
    BSET(regs_modified,acc);
786
  }else if(l==2&&!regs[ix]){
787
    emit(f,SPULL("x"));
788
    BSET(regs_modified,ix);
789
  }else if(l==2&&!regs[iy]){
790
    emit(f,SPULL("y"));
791
    BSET(regs_modified,iy);
792
#endif
793
  }else{
794
    emit(f,"\tleas\t%u,%s\n",SGN16(l),regnames[sp]);
795
  }
796
  pop(l);
797
}
798
static void pr(FILE *f,struct IC *p)
799
{
800
  int r;
801
  if(pushed_acc){
802
    emit(f,SPULLD);
803
    pop(2);
804
    pushed_acc=0;
805
  }
806
  for(r=MAXR;r>=1;r--){
807
    if(regs[r]&8){
808
      emit(f,"\t%s%s\n",CPU==6812?"pul":"puls\t",regnames[r]);
809
      pop(2);
810
    }
811
    regs[r]&=~12;
812
  }
813
}
814
static void function_top(FILE *f,struct Var *v,long offset)
815
/*  erzeugt Funktionskopf                       */
816
{
817
  int i;
818
  emit(f,"# offset=%ld\n",offset);
819
  have_frame=0;stack_valid=1;stack=0;
820
  if(!special_section(f,v)&&section!=CODE){emit(f,codename);if(f) section=CODE;}
821
  if(v->storage_class==EXTERN){
822
    if((v->flags&(INLINEFUNC|INLINEEXT))!=INLINEFUNC)
823
      emit(f,"\t.global\t%s%s\n",idprefix,v->identifier);
824
    emit(f,"%s%s:\n",idprefix,v->identifier);
825
  }else{
826
    emit(f,"%s%ld:\n",labprefix,zm2l(v->offset));
827
  }
828
  roff=0;
829
  for(i=MAXR;i>0;i--){
830
    if(regused[i]&&!regscratch[i]&&!regsa[i]){
831
      have_frame=1;
832
      loff+=2;
833
      roff+=2;
834
      if(i==iy) emit(f,SPUSH("y"));
835
      else if(i==iu){
836
        if(CPU!=6812&&regused[iy]){
837
          emit(f,"\tpshs\tu,y\n");
838
          loff+=2;roff+=2;i=iy;
839
        }else
840
          emit(f,SPUSH("u"));
841
      }else
842
        ierror(0);
843
    }
844
  }
845
  if(stack_check){
846
    stackchecklabel=++label;
847
    emit(f,"\tldy\t#%s%d\n",labprefix,stackchecklabel);
848
    /* FIXME: banked */
849
    emit(f,"\t%s\t%s__stack_check\n",jsrinst,idprefix);
850
  }
851
  if(offset){
852
    if(CPU==6812&&offset==1)
853
      emit(f,SPUSH("b"));
854
    else if(CPU==6812&&offset==2)
855
      emit(f,SPUSHD);
856
    else
857
      emit(f,"\tleas\t%ld,%s\n",SGN16(-offset),regnames[sp]);
858
    have_frame=1;
859
  }
860
}
861
static void function_bottom(FILE *f,struct Var *v,long offset)
862
/*  erzeugt Funktionsende                       */
863
{
864
  int i;
865
  offset-=roff;
866
  if(offset){
867
    if(offset==1&&CPU==6812)
868
      emit(f,"\tins\n");
869
    else if(offset==2&&CPU==6812&&!zmeqto(szof(v->vtyp->next),l2zm(4L)))
870
      emit(f,SPULL("x"));
871
    else if(offset==2&&CPU==6812&&regused[iy])
872
      emit(f,SPULL("y"));
873
    else
874
      emit(f,"\tleas\t%ld,%s\n",SGN16(offset),regnames[sp]);
875
  }
876
  for(i=1;i<=MAXR;i++){
877
    if(regused[i]&&!regscratch[i]&&!regsa[i]){
878
      have_frame=1;
879
      if(i==iy){
880
        if(CPU!=6812&&regused[iu]&&!regscratch[iu]&&!regsa[iu]){
881
          emit(f,"\tpuls\tu,y\n");
882
          i=iu;
883
        }else
884
          emit(f,SPULL("y"));
885
      }else if(i==iu) emit(f,SPULL("u"));
886
      else
887
        ierror(0);
888
    }
889
  }
890
  if(ret) emit(f,"\t%s\n",ret);
891
  if(v->storage_class==EXTERN){
892
    emit(f,"\t.type\t%s%s,@function\n",idprefix,v->identifier);
893
    emit(f,"\t.size\t%s%s,$-%s%s\n",idprefix,v->identifier,idprefix,v->identifier);
894
  }else{
895
    emit(f,"\t.type\t%s%ld,@function\n",labprefix,zm2l(v->offset));
896
    emit(f,"\t.size\t%s%ld,$-%s%ld\n",labprefix,zm2l(v->offset),labprefix,zm2l(v->offset));
897
  }
898
  if(stack_check)
899
    emit(f,"\t.equ\t%s%d,%ld\n",labprefix,stackchecklabel,offset-maxpushed);
900
  if(stack_valid){
901
    if(!v->fi) v->fi=new_fi();
902
    v->fi->flags|=ALL_STACK;
903
    v->fi->stack1=l2zm(stack+offset);
904
    emit(f,"# stacksize=%ld\n",stack+offset);
905
    emit(f,"\t.equ\t%s__stack_%s,%ld\n",idprefix,v->identifier,stack+offset);
906
  }
907
}
908
static int compare_objects(struct obj *o1,struct obj *o2)
909
{
910
  if(o1->flags==o2->flags&&o1->am==o2->am){
911
    if(!(o1->flags&VAR)||(o1->v==o2->v&&zmeqto(o1->val.vmax,o2->val.vmax))){
912
      if(!(o1->flags&REG)||o1->reg==o2->reg){
913
        return 1;
914
      }
915
    }
916
  }
917
  return 0;
918
}
919
 
920
/*FIXME*/
921
static void clear_ext_ic(struct ext_ic *p)
922
{
923
  p->flags=0;
924
  p->r=0;
925
  p->offset=0;
926
}
927
static long pof2(zumax x)
928
/*  Yields log2(x)+1 oder 0. */
929
{
930
  zumax p;int ln=1;
931
  p=ul2zum(1L);
932
  while(ln<=32&&zumleq(p,x)){
933
    if(zumeqto(x,p)) return ln;
934
    ln++;p=zumadd(p,p);
935
  }
936
  return 0;
937
}
938
static void peephole(struct IC *p)
939
{
940
  int c,c2,r,t;struct IC *p2;
941
  struct AddressingMode *am;
942
  zmax incmin,incmax;
943
  if(CPU==6812){
944
    incmin=l2zm(-8L);
945
    incmax=l2zm(8L);
946
  }else{
947
    incmin=l2zm(-2L);
948
    incmax=l2zm(2L);
949
  }
950
  frame_used=0;
951
  for(;p;p=p->next){
952
    c=p->code;
953
    if(!frame_used){
954
      if((p->q1.flags&(REG|VAR))==VAR&&!ISSTATIC(p->q1.v)) frame_used=1;
955
      if((p->q2.flags&(REG|VAR))==VAR&&!ISSTATIC(p->q2.v)) frame_used=1;
956
      if((p->z.flags&(REG|VAR))==VAR&&!ISSTATIC(p->z.v)) frame_used=1;
957
    }
958
    /* letztes Label merken */
959
    if(c!=FREEREG&&c!=ALLOCREG&&(c!=SETRETURN||!isreg(q1)||p->q1.reg!=p->z.reg)) exit_label=0;
960
    if(c==LABEL) exit_label=p->typf;
961
#if 0
962
    /* and x,#const;bne/beq, FIXME */
963
    if(c==AND&&isconst(q2)&&isreg(z)){
964
      long bit;
965
      eval_const(&p->q2.val,p->typf);
966
      if(bit=pof2(vumax)){
967
        struct IC *cmp=0;int fr=0;
968
        for(p2=p->next;p2;p2=p2->next){
969
          c2=p2->code;
970
          if(c2==TEST){
971
            if((p2->q1.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==p->z.reg){
972
              cmp=p2;continue;
973
            }
974
          }
975
          if(c2==COMPARE&&(p2->q1.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==p->z.reg&&(p2->q2.flags&(KONST|DREFOBJ))==KONST){
976
            eval_const(&p2->q2.val,p2->typf);
977
            if(ISNULL()){
978
              cmp=p2;continue;
979
            }
980
            break;
981
          }
982
          if(c2==FREEREG&&p2->q1.reg==p->z.reg) {fr++;continue;}
983
          if((c2==BNE||c2==BEQ)&&cmp&&fr==1){
984
            p->ext.flags=EXT_IC_BTST;
985
            p2->ext.flags=EXT_IC_BTST;
986
            p2->ext.offset=bit-1;
987
            cmp->code=NOP;
988
            cmp->q1.flags=cmp->q2.flags=cmp->z.flags=0;
989
            break;
990
          }
991
          if(((p2->q1.flags&REG)&&p2->q1.reg==p->z.reg)||((p2->q2.flags&REG)&&p2->q2.reg==p->z.reg)||((p2->z.flags&REG)&&p2->z.reg==p->z.reg)) break;
992
          if(c2==CALL||c2==LABEL||(c2>=BEQ&&c2<=BRA)) break;
993
        }
994
      }
995
    }
996
#endif
997
    /* Try d,idx */
998
    if(c==ADDI2P&&ISRACC(q2)&&ISRIDX(z)&&(ISRIDX(q1)||p->q2.reg!=p->z.reg)){
999
      int base,idx;struct obj *o;
1000
      r=p->z.reg;idx=p->q2.reg;
1001
      if(isreg(q1)) base=p->q1.reg; else base=r;
1002
      o=0;
1003
      for(p2=p->next;p2;p2=p2->next){
1004
        c2=p2->code;
1005
        if(c2==CALL||c2==LABEL||(c2>=BEQ&&c2<=BRA)) break;
1006
        if(c2!=FREEREG&&(p2->q1.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==r) break;
1007
        if(c2!=FREEREG&&(p2->q2.flags&(REG|DREFOBJ))==REG&&p2->q2.reg==r) break;
1008
        if((p2->z.flags&(REG|DREFOBJ))==REG&&p2->z.reg==idx&&idx!=r) break;
1009
 
1010
        if(c2!=CALL&&(c2<LABEL||c2>BRA)/*&&c2!=ADDRESS*/){
1011
          if(!p2->q1.am&&(p2->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->q1.reg==r){
1012
            if(o||!ISCHWORD(q1typ(p2))) break;
1013
            o=&p2->q1;
1014
          }
1015
          if(!p2->q2.am&&(p2->q2.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->q2.reg==r){
1016
            break; /*TODO: check what is possible */
1017
            if(o||!ISCHWORD(q2typ(p2))) break;
1018
            o=&p2->q2;
1019
          }
1020
          if(!p2->z.am&&(p2->z.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->z.reg==r){
1021
            break; /*TODO: check what is possible */
1022
            if(o||!ISCHWORD(ztyp(p2))) break;
1023
            o=&p2->z;
1024
          }
1025
        }
1026
        if(c2==FREEREG||(p2->z.flags&(REG|DREFOBJ))==REG){
1027
          int m;
1028
          if(c2==FREEREG)
1029
            m=p2->q1.reg;
1030
          else
1031
            m=p2->z.reg;
1032
          if(m==r){
1033
            if(o){
1034
              o->am=am=mymalloc(sizeof(*am));
1035
              am->flags=ACC_IND;
1036
              am->base=base;
1037
              if(idx!=acc) ierror(0);
1038
              am->offset=idx;
1039
              if(isreg(q1)){
1040
                p->code=c=NOP;p->q1.flags=p->q2.flags=p->z.flags=0;
1041
              }else{
1042
                p->code=c=ASSIGN;p->q2.flags=0;
1043
                p->typf=p->typf2;p->q2.val.vmax=sizetab[p->typf2&NQ];
1044
              }
1045
            }
1046
            break;
1047
          }
1048
          if(c2!=FREEREG&&m==base) break;
1049
          continue;
1050
        }
1051
        /* better no instructions between, accu used too much */
1052
        if(c2!=FREEREG&&c2!=ALLOCREG&&!o) break;
1053
      }
1054
    }
1055
    /* POST_INC/DEC in q1 */
1056
    if(!p->q1.am&&(p->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)){
1057
      r=p->q1.reg; t=q1typ(p);
1058
      if(ISCHWORD(t)&&ISIDX(r)&&(!(p->q2.flags&REG)||p->q2.reg!=r)&&(!(p->z.flags&REG)||p->z.reg!=r)){
1059
        for(p2=p->next;p2;p2=p2->next){
1060
          c2=p2->code;
1061
          if((c2==ADD||c2==ADDI2P||(CPU==6812&&(c2==SUB||c2==SUBIFP)))&&(p2->q1.flags&(REG|DREFOBJ))==REG&&(p2->z.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==r&&p2->z.reg==r&&(p2->q2.flags&(KONST|DREFOBJ))==KONST){
1062
            eval_const(&p2->q2.val,p2->typf2);
1063
            if(c2==SUB||c2==SUBIFP) vmax=zmsub(l2zm(0L),vmax);
1064
            if(zmleq(vmax,incmax)&&zmleq(incmin,vmax)){
1065
              p2->code=NOP;
1066
              p2->q1.flags=p2->q2.flags=p2->z.flags=0;
1067
              p->q1.am=mymalloc(sizeof(*am));
1068
              p->q1.am->base=r;
1069
              p->q1.am->v=0;
1070
              if(zmleq(vmax,l2zm(0L))){
1071
                p->q1.am->flags=POST_DEC;
1072
                p->q1.am->offset=-zm2l(vmax);
1073
              }else{
1074
                p->q1.am->flags=POST_INC;
1075
                p->q1.am->offset=zm2l(vmax);
1076
              }
1077
            }else break;
1078
          }
1079
          if(c2==CALL||c2==LABEL||(c2>=BEQ&&c2<=BRA)) break;
1080
          if(((p2->q1.flags&REG)&&p2->q1.reg==r)||((p2->q2.flags&REG)&&p2->q2.reg==r)||((p2->z.flags&REG)&&p2->z.reg==r)) break;
1081
        }
1082
      }
1083
    }
1084
    /* POST_INC/DEC in q2 */
1085
    if(!p->q2.am&&(p->q2.flags&(REG|DREFOBJ))==(REG|DREFOBJ)){
1086
      r=p->q2.reg; t=q2typ(p);
1087
      if(ISCHWORD(t)&&ISIDX(r)&&(!(p->q1.flags&REG)||p->q1.reg!=r)&&(!(p->z.flags&REG)||p->z.reg!=r)){
1088
        for(p2=p->next;p2;p2=p2->next){
1089
          c2=p2->code;
1090
          if((c2==ADD||c2==ADDI2P||(CPU==6812&&(c2==SUB||c2==SUBIFP)))&&(p2->q1.flags&(REG|DREFOBJ))==REG&&(p2->z.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==r&&p2->z.reg==r&&(p2->q2.flags&(KONST|DREFOBJ))==KONST){
1091
            eval_const(&p2->q2.val,p2->typf2);
1092
            if(c2==SUB||c2==SUBIFP) vmax=zmsub(l2zm(0L),vmax);
1093
            if(zmleq(vmax,incmax)&&zmleq(incmin,vmax)){
1094
              p2->code=NOP;
1095
              p2->q1.flags=p2->q2.flags=p2->z.flags=0;
1096
              p->q2.am=mymalloc(sizeof(*am));
1097
              p->q2.am->base=r;
1098
              p->q2.am->v=0;
1099
              if(zmleq(vmax,l2zm(0L))){
1100
                p->q2.am->flags=POST_DEC;
1101
                p->q2.am->offset=-zm2l(vmax);
1102
              }else{
1103
                p->q2.am->flags=POST_INC;
1104
                p->q2.am->offset=zm2l(vmax);
1105
              }
1106
            }else break;
1107
          }
1108
          if(c2==CALL||c2==LABEL||(c2>=BEQ&&c2<=BRA)) break;
1109
          if(((p2->q1.flags&REG)&&p2->q1.reg==r)||((p2->q2.flags&REG)&&p2->q2.reg==r)||((p2->z.flags&REG)&&p2->z.reg==r)) break;
1110
        }
1111
      }
1112
    }
1113
    /* POST_INC/DEC in z */
1114
    if(!p->z.am&&(p->z.flags&(REG|DREFOBJ))==(REG|DREFOBJ)){
1115
      r=p->z.reg; t=ztyp(p);
1116
      if(ISCHWORD(t)&&ISIDX(r)&&(!(p->q1.flags&REG)||p->q1.reg!=r)&&(!(p->q2.flags&REG)||p->q2.reg!=r)){
1117
        for(p2=p->next;p2;p2=p2->next){
1118
          c2=p2->code;
1119
          if((c2==ADD||c2==ADDI2P||(CPU==6812&&(c2==SUB||c2==SUBIFP)))&&(p2->q1.flags&(REG|DREFOBJ))==REG&&(p2->z.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==r&&p2->z.reg==r&&(p2->q2.flags&(KONST|DREFOBJ))==KONST){
1120
            eval_const(&p2->q2.val,p2->typf2);
1121
            if(c2==SUB||c2==SUBIFP) vmax=zmsub(l2zm(0L),vmax);
1122
            if(zmleq(vmax,incmax)&&zmleq(incmin,vmax)){
1123
              p2->code=NOP;
1124
              p2->q1.flags=p2->q2.flags=p2->z.flags=0;
1125
              p->z.am=mymalloc(sizeof(*am));
1126
              p->z.am->base=r;
1127
              p->z.am->v=0;
1128
              if(zmleq(vmax,l2zm(0L))){
1129
                p->z.am->flags=POST_DEC;
1130
                p->z.am->offset=-zm2l(vmax);
1131
              }else{
1132
                p->z.am->flags=POST_INC;
1133
                p->z.am->offset=zm2l(vmax);
1134
              }
1135
            }else break;
1136
          }
1137
          if(c2==CALL||c2==LABEL||(c2>=BEQ&&c2<=BRA)) break;
1138
          if(((p2->q1.flags&REG)&&p2->q1.reg==r)||((p2->q2.flags&REG)&&p2->q2.reg==r)||((p2->z.flags&REG)&&p2->z.reg==r)) break;
1139
        }
1140
      }
1141
    }
1142
 
1143
    /* R,#c */
1144
    if((c==ADDI2P||c==SUBIFP)&&ISHWORD(p->typf)&&((p->typf2&NQ)==NPOINTER||(p->typf2&NQ)==FPOINTER)&&isreg(z)&&((p->q2.flags&(KONST|DREFOBJ))==KONST||(!drel&&(p->q1.flags&VARADR)))){
1145
      int base;zmax of;struct obj *o;struct Var *v;
1146
      if(p->q1.flags&VARADR){
1147
        v=p->q1.v;
1148
        of=p->q1.val.vmax;
1149
        r=p->z.reg;
1150
        if(isreg(q2)&&ISIDX(p->q2.reg))
1151
          base=p->q2.reg;
1152
        else
1153
          base=r;
1154
      }else{
1155
        eval_const(&p->q2.val,p->typf);
1156
        if(c==SUBIFP) of=zmsub(l2zm(0L),vmax); else of=vmax;
1157
        v=0;
1158
        r=p->z.reg;
1159
        if(isreg(q1)&&ISIDX(p->q1.reg)) base=p->q1.reg; else base=r;
1160
      }
1161
      o=0;
1162
      for(p2=p->next;p2;p2=p2->next){
1163
        c2=p2->code;
1164
        if(c2==CALL||c2==LABEL||(c2>=BEQ&&c2<=BRA)) break;
1165
        if(c2!=FREEREG&&(p2->q1.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==r) break;
1166
        if(c2!=FREEREG&&(p2->q2.flags&(REG|DREFOBJ))==REG&&p2->q2.reg==r) break;
1167
        if(c2!=CALL&&(c2<LABEL||c2>BRA)/*&&c2!=ADDRESS*/){
1168
          if(!p2->q1.am&&(p2->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->q1.reg==r){
1169
            if(o||!ISHWORD(q1typ(p2))) break;
1170
            o=&p2->q1;
1171
          }
1172
          if(!p2->q2.am&&(p2->q2.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->q2.reg==r){
1173
            if(o||!ISHWORD(q2typ(p2))) break;
1174
            o=&p2->q2;
1175
          }
1176
          if(!p2->z.am&&(p2->z.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->z.reg==r){
1177
            if(o||!ISHWORD(ztyp(p2))) break;
1178
            o=&p2->z;
1179
          }
1180
        }
1181
        if(c2==FREEREG||(p2->z.flags&(REG|DREFOBJ))==REG){
1182
          int m;
1183
          if(c2==FREEREG)
1184
            m=p2->q1.reg;
1185
          else
1186
            m=p2->z.reg;
1187
          if(m==r){
1188
            if(o){
1189
              o->am=am=mymalloc(sizeof(*am));
1190
              am->flags=IMM_IND;
1191
              am->base=base;
1192
              am->offset=zm2l(of);
1193
              am->v=v;
1194
              if(!v){
1195
                if(isreg(q1)&&ISIDX(p->q1.reg)){
1196
                  p->code=c=NOP;p->q1.flags=p->q2.flags=p->z.flags=0;
1197
                }else{
1198
                  p->code=c=ASSIGN;p->q2.flags=0;
1199
                  p->typf=p->typf2;p->q2.val.vmax=sizetab[p->typf2&NQ];
1200
                }
1201
              }else{
1202
                if(isreg(q2)&&ISIDX(p->q2.reg)){
1203
                  p->code=c=NOP;p->q1.flags=p->q2.flags=p->z.flags=0;
1204
                }else{
1205
                  p->code=c=ASSIGN;p->q1=p->q2;p->q2.flags=0;
1206
                  p->q2.val.vmax=sizetab[p->typf&NQ];
1207
                }
1208
              }
1209
            }
1210
            break;
1211
          }
1212
          if(/*get_reg!! c2!=FREEREG&&*/m==base) break;
1213
          continue;
1214
        }
1215
      }
1216
    }
1217
  }
1218
}
1219
 
1220
static struct obj *cam(int flags,int base,long offset,struct Var *v)
1221
/*  Initializes an addressing-mode structure and returns a pointer to   */
1222
/*  that object. Will not survive a second call!                        */
1223
{
1224
  static struct obj obj;
1225
  static struct AddressingMode am;
1226
  obj.am=&am;
1227
  am.flags=flags;
1228
  am.base=base;
1229
  am.offset=offset;
1230
  am.v=v;
1231
  return &obj;
1232
}
1233
 
1234
static void get_acc(FILE *f,struct IC *p)
1235
{
1236
  if(regs[acc]){
1237
    if(p->q2.am)
1238
      if(p->q2.am->flags==ACC_IND) ierror(0);
1239
    else
1240
      if((p->q2.flags&REG)&&ISACC(p->q2.reg)) ierror(0);
1241
    if(p->z.am)
1242
      if(p->z.am->flags==ACC_IND) ierror(0);
1243
    else
1244
      if((p->z.flags&REG)&&ISACC(p->z.reg)) ierror(0);
1245
    if(regs[acc]){
1246
      emit(f,SPUSHD);
1247
      push(2);
1248
      pushed_acc=1;
1249
    }
1250
  }
1251
}
1252
static int get_idx(FILE *f,IC *p)
1253
{
1254
  int r;
1255
  for(r=1;r<=MAXR;r++){
1256
    if(ISIDX(r)){
1257
      if(!regs[r]){
1258
        regs[r]|=4;
1259
        return r;
1260
      }
1261
    }
1262
  }
1263
  for(r=1;r<=MAXR;r++){
1264
    if(ISIDX(r)){
1265
      if((!(p->q1.flags&REG)||p->q1.reg!=r)&&
1266
         (!(p->q2.flags&REG)||p->q2.reg!=r)&&
1267
         (!(p->z.flags&REG)||p->z.reg!=r)){
1268
        emit(f,"\t%s%s\n",CPU==6812?"psh":"pshs\t",regnames[r]);
1269
        regs[r]|=8;
1270
        push(2);
1271
        return r;
1272
      }
1273
    }
1274
  }
1275
  ierror(0);
1276
}
1277
static int get_reg(FILE *f,struct IC *p,int t)
1278
{
1279
  int reg;
1280
  if(!regs[acc])
1281
    reg=acc;
1282
  else if(ISHWORD(t)&&!regs[ix])
1283
    reg=ix;
1284
#if 0
1285
  else if(ISHWORD(t)&&!regs[iy])
1286
    reg=iy;
1287
#endif
1288
  else{
1289
    get_acc(f,p);
1290
    reg=acc;
1291
  }
1292
  BSET(regs_modified,reg);
1293
  return reg;
1294
}
1295
static void load_reg(FILE *f,int r,struct obj *o,int t)
1296
{
1297
  if(!o->am){
1298
    if((o->flags&(REG|DREFOBJ))==REG){
1299
      if(o->reg==r) return;
1300
      emit(f,"\ttfr\t%s,%s\n",regnames[o->reg],regnames[r]);
1301
      return;
1302
    }
1303
    if(r==acc&&(o->flags&(KONST|DREFOBJ))==KONST){
1304
      eval_const(&o->val,t);
1305
      if(zmeqto(vmax,l2zm(0L))&&zumeqto(vumax,ul2zum(0UL))){
1306
        if(CPU!=6812&&!optsize)
1307
          emit(f,"\tldd\t#0\n");
1308
        else
1309
          emit(f,"\tclra\n\tclrb\n");
1310
        cc=o;cc_t=t;
1311
        return;
1312
      }
1313
    }
1314
  }
1315
  if(o->flags&VARADR){
1316
    char *base=0;
1317
    if(pcrel&&ISFUNC(o->v->vtyp->flags))
1318
      base="pc";
1319
    if(drel&&!ISFUNC(o->v->vtyp->flags))
1320
      base=regnames[iu];
1321
    if(base&&!skip_rel){
1322
      if(ISACC(r))
1323
        emit(f,"\ttfr\t%s,d\n",base);
1324
      if(ISIDX(r))
1325
        emit(f,"\tlea%s\t",regnames[r]);
1326
      else{
1327
        if(*base=='p') emit(f,"%s%d:\n",labprefix,++label);
1328
        emit(f,"\taddd\t#");
1329
      }
1330
      emitzm(f,o->val.vmax);
1331
      emit(f,"+");
1332
      if(o->v->storage_class==EXTERN)
1333
        emit(f,"%s%s",idprefix,o->v->identifier);
1334
      else
1335
        emit(f,"%s%ld",labprefix,zm2l(o->v->offset));
1336
      if(ISIDX(r))
1337
        emit(f,",%s",base);
1338
      else if(*base=='p')
1339
        emit(f,"-%s%d",labprefix,label);
1340
      emit(f,"\n");
1341
      cc=o;cc_t=t;
1342
      return;
1343
    }
1344
    skip_rel=0;
1345
  }
1346
  emit(f,"\tld%s\t",(r==acc&&(t&NQ)==CHAR)?(CPU==6812?"ab":"b"):regnames[r]);
1347
  emit_obj(f,o,t);emit(f,"\n");
1348
  cc=o;cc_t=t;
1349
}
1350
static void store_reg(FILE *f,int r,struct obj *o,int t)
1351
{
1352
  if((o->flags&(REG|DREFOBJ))==REG){
1353
    if(o->reg==r) return;
1354
    emit(f,"\ttfr\t%s,%s\n",regnames[r],regnames[o->reg]);
1355
  }else{
1356
    if(r==acc&&(t&NQ)==CHAR)
1357
      emit(f,"\tst%s\t",(CPU==6812)?"ab":"b");
1358
    else
1359
      emit(f,"\tst%s\t",regnames[r]);
1360
    emit_obj(f,o,t);emit(f,"\n");
1361
    cc=o;cc_t=t;
1362
  }
1363
}
1364
static void load_addr(FILE *f,int r,struct obj *o)
1365
{
1366
  if(o->am){
1367
    if(o->am->flags==IMM_IND){
1368
      if(o->am->base==r&&o->am->offset==0&&!o->am->v) return;
1369
      if(ISIDX(r)){
1370
        emit(f,"\tlea%s\t",regnames[r]);
1371
        emit_obj(f,o,0);
1372
        emit(f,"\n");
1373
      }else{
1374
        if(r!=acc) ierror(0);
1375
        emit(f,"\ttfr\t%s,%s\n",regnames[o->am->base],regnames[r]);
1376
        emit(f,"\taddd\t#%ld\n",o->am->offset);
1377
        if(o->am->v){
1378
          if(o->am->v->storage_class==STATIC)
1379
            emit(f,"+%s%ld",labprefix,zm2l(o->am->v->offset));
1380
          else
1381
            emit(f,"+%s%s",idprefix,o->am->v->identifier);
1382
        }
1383
        emit(f,"\n");
1384
        cc=0;
1385
      }
1386
      return;
1387
    }
1388
    ierror(0);
1389
  }
1390
  if(o->flags&DREFOBJ){
1391
    o->flags&=~DREFOBJ;
1392
    load_reg(f,r,o,o->dtyp);
1393
    o->flags|=DREFOBJ;
1394
    return;
1395
  }
1396
  if((o->flags&(VAR|VARADR))==VAR){
1397
    if(o->v->storage_class==STATIC||o->v->storage_class==EXTERN){
1398
      o->flags|=VARADR;
1399
      load_reg(f,r,o,POINTER_TYPE(o->v->vtyp));
1400
      o->flags&=~VARADR;
1401
      return;
1402
    }
1403
    if(voff(o)==0){
1404
      emit(f,"\ttfr\t%s,%s\n",regnames[sp],regnames[r]);
1405
      return;
1406
    }
1407
    if(ISIDX(r)){
1408
      emit(f,"\tlea%s\t",regnames[r]);
1409
      emit_obj(f,o,0);
1410
      emit(f,"\n");
1411
    }else{
1412
      if(r!=acc) ierror(0);
1413
      emit(f,"\ttfr\t%s,%s\n",regnames[sp],regnames[r]);
1414
      emit(f,"\taddd\t#%ld\n",voff(o));
1415
      cc=0;
1416
    }
1417
    return;
1418
  }
1419
  ierror(0);
1420
}
1421
 
1422
static int scratchreg(int r,struct IC *p)
1423
{
1424
  int c;
1425
  while(1){
1426
    p=p->next;
1427
    if(!p||((c=p->code)==FREEREG&&p->q1.reg==r)) return 1;
1428
    if(c==CALL||(c>=BEQ&&c<=BRA)) return 0;
1429
    if((p->q1.flags&REG)&&p->q1.reg==r) return 0;
1430
    if((p->q2.flags&REG)&&p->q2.reg==r) return 0;
1431
    if((p->z.flags&REG)&&p->z.reg==r) return 0;
1432
  }
1433
}
1434
 
1435
/****************************************/
1436
/*  End of private fata and functions.  */
1437
/****************************************/
1438
 
1439
 
1440
int init_cg(void)
1441
/*  Does necessary initializations for the code-generator. Gets called  */
1442
/*  once at the beginning and should return 0 in case of problems.      */
1443
{
1444
  int i;
1445
 
1446
  CPU=CPUOPT;
1447
 
1448
        if (CPU==680912) {
1449
                bitsperbyte = 12;
1450
                bytemask = 0xfff;
1451
                dbl_bytemask = 0xffffff;
1452
        }
1453
 
1454
  /*  Initialize some values which cannot be statically initialized   */
1455
  /*  because they are stored in the target's arithmetic.             */
1456
  maxalign=l2zm(1L);
1457
  char_bit=l2zm((long)bitsperbyte);
1458
  for(i=0;i<=MAX_TYPE;i++){
1459
    sizetab[i]=l2zm(msizetab[i]);
1460
    align[i]=l2zm(malign[i]);
1461
  }
1462
  for(i=1;i<=iu;i++){
1463
    regsize[i]=l2zm(2L);regtype[i]=&ityp;
1464
  }
1465
  regsize[dx]=l2zm(4L);regtype[i]=&ltyp;
1466
 
1467
  /*  Initialize the min/max-settings. Note that the types of the     */
1468
  /*  host system may be different from the target system and you may */
1469
  /*  only use the smallest maximum values ANSI guarantees if you     */
1470
  /*  want to be portable.                                            */
1471
  /*  That's the reason for the subtraction in t_min[INT]. Long could */
1472
  /*  be unable to represent -2147483648 on the host system.          */
1473
  if (CPU==680912) {
1474
          t_min[CHAR]=l2zm(-2048L);
1475
          t_min[SHORT]=l2zm(-8388608L);
1476
          t_min[INT]=t_min[SHORT];
1477
          t_min[LONG]=zmsub(l2zm(0x800000000000LL),l2zm(1L));
1478
          t_min[LLONG]=zmlshift(l2zm(1L),l2zm(63L));
1479
          t_min[MAXINT]=t_min(LLONG);
1480
          t_max[CHAR]=ul2zum(2047L);
1481
          t_max[SHORT]=ul2zum(8388607UL);
1482
          t_max[INT]=t_max[SHORT];
1483
          t_max[LONG]=ul2zum(0x7fffffffffffULL);
1484
          t_max[LLONG]=zumrshift(zumkompl(ul2zum(0UL)),ul2zum(1UL));
1485
          t_max[MAXINT]=t_max(LLONG);
1486
          tu_max[CHAR]=ul2zum(4095UL);
1487
          tu_max[SHORT]=ul2zum(16777215UL);
1488
          tu_max[INT]=tu_max[SHORT];
1489
          tu_max[LONG]=ul2zum(0xffffffffffffULL);
1490
          tu_max[LLONG]=zumkompl(ul2zum(0UL));
1491
          tu_max[MAXINT]=t_max(UNSIGNED|LLONG);
1492
        }
1493
        else {
1494
          t_min[CHAR]=l2zm(-128L);
1495
          t_min[SHORT]=l2zm(-32768L);
1496
          t_min[INT]=t_min[SHORT];
1497
          t_min[LONG]=zmsub(l2zm(-2147483647L),l2zm(1L));
1498
          t_min[LLONG]=zmlshift(l2zm(1L),l2zm(63L));
1499
          t_min[MAXINT]=t_min(LLONG);
1500
          t_max[CHAR]=ul2zum(127L);
1501
          t_max[SHORT]=ul2zum(32767UL);
1502
          t_max[INT]=t_max[SHORT];
1503
          t_max[LONG]=ul2zum(2147483647UL);
1504
          t_max[LLONG]=zumrshift(zumkompl(ul2zum(0UL)),ul2zum(1UL));
1505
          t_max[MAXINT]=t_max(LLONG);
1506
          tu_max[CHAR]=ul2zum(255UL);
1507
          tu_max[SHORT]=ul2zum(65535UL);
1508
          tu_max[INT]=tu_max[SHORT];
1509
          tu_max[LONG]=ul2zum(4294967295UL);
1510
          tu_max[LLONG]=zumkompl(ul2zum(0UL));
1511
          tu_max[MAXINT]=t_max(UNSIGNED|LLONG);
1512
        }
1513
 
1514
  if(g_flags[9]&USEDFLAG) drel=1;
1515
  if(g_flags[10]&USEDFLAG) MINADDI2P=SHORT;
1516
  if(g_flags[11]&USEDFLAG) nodx=1;
1517
  if(g_flags[12]&USEDFLAG) nou=1;
1518
 
1519
  if(CPU==6812) switchsubs=1;
1520
 
1521
  /*  Reserve a few registers for use by the code-generator.      */
1522
  regsa[sp]=REGSA_NEVER;
1523
  regscratch[sp]=0;
1524
 
1525
  if(CPU==6812||drel||nou){
1526
    regsa[iu]=REGSA_NEVER;
1527
    regscratch[iu]=0;
1528
  }
1529
 
1530
  if(CPU!=6812){
1531
    regnames[sp]="s";
1532
    logicals[0]="or";
1533
  }
1534
 
1535
  if(!(g_flags[6]&USEDFLAG)){
1536
    extern int static_cse,dref_cse;
1537
    static_cse=0;
1538
    dref_cse=0;
1539
  }
1540
 
1541
  if(!(g_flags[7]&USEDFLAG)){
1542
    regsa[acc]=REGSA_TEMPS;
1543
    regsa[dx]=REGSA_TEMPS;
1544
  }
1545
 
1546
  if(g_flags[8]&USEDFLAG){
1547
    pcrel=1;
1548
    jsrinst="lbsr";
1549
    jmpinst="lbra";
1550
    rodataname="\t.data\n";
1551
  }
1552
 
1553
  if(CPU==6809)
1554
    marray[1]="__6809__";
1555
  if(CPU==6309)
1556
    marray[1]="__6309__";
1557
  if(CPU==680912)
1558
    marray[1]="__680912__";
1559
  target_macros=marray;
1560
 
1561
 
1562
  declare_builtin("__mulint16",INT,INT,acc,INT,0,1,0);
1563
  declare_builtin("__divint16",INT,INT,ix,INT,acc,1,0);
1564
  declare_builtin("__divuint16",UNSIGNED|INT,UNSIGNED|INT,ix,UNSIGNED|INT,acc,1,0);
1565
  declare_builtin("__modint16",INT,INT,ix,INT,acc,1,0);
1566
  declare_builtin("__moduint16",UNSIGNED|INT,UNSIGNED|INT,ix,UNSIGNED|INT,acc,1,0);
1567
 
1568
 
1569
  /* TODO: set argument registers */
1570
  declare_builtin("__mulint32",LONG,LONG,0,LONG,0,1,0);
1571
  declare_builtin("__addint32",LONG,LONG,0,LONG,0,1,0);
1572
  declare_builtin("__subint32",LONG,LONG,0,LONG,0,1,0);
1573
  declare_builtin("__andint32",LONG,LONG,0,LONG,0,1,0);
1574
  declare_builtin("__orint32",LONG,LONG,0,LONG,0,1,0);
1575
  declare_builtin("__eorint32",LONG,LONG,0,LONG,0,1,0);
1576
  declare_builtin("__negint32",LONG,LONG,0,0,0,1,0);
1577
  declare_builtin("__lslint32",LONG,LONG,0,INT,0,1,0);
1578
 
1579
  declare_builtin("__divint32",LONG,LONG,0,LONG,0,1,0);
1580
  declare_builtin("__divuint32",UNSIGNED|LONG,UNSIGNED|LONG,0,UNSIGNED|LONG,0,1,0);
1581
  declare_builtin("__modint32",LONG,LONG,0,LONG,0,1,0);
1582
  declare_builtin("__moduint32",UNSIGNED|LONG,UNSIGNED|LONG,0,UNSIGNED|LONG,0,1,0);
1583
  declare_builtin("__lsrsint32",LONG,LONG,0,INT,0,1,0);
1584
  declare_builtin("__lsruint32",UNSIGNED|LONG,UNSIGNED|LONG,0,INT,0,1,0);
1585
  declare_builtin("__cmpsint32",INT,LONG,0,LONG,0,1,0);
1586
  declare_builtin("__cmpuint32",INT,UNSIGNED|LONG,0,UNSIGNED|LONG,0,1,0);
1587
  declare_builtin("__sint32toflt32",FLOAT,LONG,0,0,0,1,0);
1588
  declare_builtin("__uint32toflt32",FLOAT,UNSIGNED|LONG,0,0,0,1,0);
1589
  declare_builtin("__sint32toflt64",DOUBLE,LONG,0,0,0,1,0);
1590
  declare_builtin("__uint32toflt64",DOUBLE,UNSIGNED|LONG,0,0,0,1,0);
1591
  declare_builtin("__flt32tosint32",LONG,FLOAT,0,0,0,1,0);
1592
  declare_builtin("__flt32touint32",UNSIGNED|LONG,FLOAT,0,0,0,1,0);
1593
  declare_builtin("__flt64tosint32",LONG,DOUBLE,0,0,0,1,0);
1594
  declare_builtin("__flt64touint32",UNSIGNED|LONG,DOUBLE,0,0,0,1,0);
1595
 
1596
 
1597
 
1598
  declare_builtin("__mulint64",LLONG,LLONG,0,LLONG,0,1,0);
1599
  declare_builtin("__addint64",LLONG,LLONG,0,LLONG,0,1,0);
1600
  declare_builtin("__subint64",LLONG,LLONG,0,LLONG,0,1,0);
1601
  declare_builtin("__andint64",LLONG,LLONG,0,LLONG,0,1,0);
1602
  declare_builtin("__orint64",LLONG,LLONG,0,LLONG,0,1,0);
1603
  declare_builtin("__eorint64",LLONG,LLONG,0,LLONG,0,1,0);
1604
  declare_builtin("__negint64",LLONG,LLONG,0,0,0,1,0);
1605
  declare_builtin("__lslint64",LLONG,LLONG,0,INT,0,1,0);
1606
 
1607
  declare_builtin("__divsint64",LLONG,LLONG,0,LLONG,0,1,0);
1608
  declare_builtin("__divuint64",UNSIGNED|LLONG,UNSIGNED|LLONG,0,UNSIGNED|LLONG,0,1,0);
1609
  declare_builtin("__modsint64",LLONG,LLONG,0,LLONG,0,1,0);
1610
  declare_builtin("__moduint64",UNSIGNED|LLONG,UNSIGNED|LLONG,0,UNSIGNED|LLONG,0,1,0);
1611
  declare_builtin("__lsrsint64",LLONG,LLONG,0,INT,0,1,0);
1612
  declare_builtin("__lsruint64",UNSIGNED|LLONG,UNSIGNED|LLONG,0,INT,0,1,0);
1613
  declare_builtin("__cmpsint64",INT,LLONG,0,LLONG,0,1,0);
1614
  declare_builtin("__cmpuint64",INT,UNSIGNED|LLONG,0,UNSIGNED|LLONG,0,1,0);
1615
  declare_builtin("__sint64toflt32",FLOAT,LLONG,0,0,0,1,0);
1616
  declare_builtin("__uint64toflt32",FLOAT,UNSIGNED|LLONG,0,0,0,1,0);
1617
  declare_builtin("__sint64toflt64",DOUBLE,LLONG,0,0,0,1,0);
1618
  declare_builtin("__uint64toflt64",DOUBLE,UNSIGNED|LLONG,0,0,0,1,0);
1619
  declare_builtin("__flt32tosint64",LLONG,FLOAT,0,0,0,1,0);
1620
  declare_builtin("__flt32touint64",UNSIGNED|LLONG,FLOAT,0,0,0,1,0);
1621
  declare_builtin("__flt64tosint64",LLONG,DOUBLE,0,0,0,1,0);
1622
  declare_builtin("__flt64touint64",UNSIGNED|LLONG,DOUBLE,0,0,0,1,0);
1623
 
1624
  declare_builtin("__flt32toflt64",DOUBLE,FLOAT,0,0,0,1,0);
1625
  declare_builtin("__flt64toflt32",FLOAT,DOUBLE,0,0,0,1,0);
1626
 
1627
 
1628
  declare_builtin("__addflt32",FLOAT,FLOAT,0,FLOAT,0,1,0);
1629
  declare_builtin("__subflt32",FLOAT,FLOAT,0,FLOAT,0,1,0);
1630
  declare_builtin("__mulflt32",FLOAT,FLOAT,0,FLOAT,0,1,0);
1631
  declare_builtin("__divflt32",FLOAT,FLOAT,0,FLOAT,0,1,0);
1632
  declare_builtin("__negflt32",FLOAT,FLOAT,0,FLOAT,0,1,0);
1633
  declare_builtin("__cmpflt32",INT,FLOAT,0,FLOAT,0,1,0);
1634
 
1635
  declare_builtin("__addflt64",DOUBLE,DOUBLE,0,DOUBLE,0,1,0);
1636
  declare_builtin("__subflt64",DOUBLE,DOUBLE,0,DOUBLE,0,1,0);
1637
  declare_builtin("__mulflt64",DOUBLE,DOUBLE,0,DOUBLE,0,1,0);
1638
  declare_builtin("__divflt64",DOUBLE,DOUBLE,0,DOUBLE,0,1,0);
1639
  declare_builtin("__negflt64",DOUBLE,DOUBLE,0,DOUBLE,0,1,0);
1640
  declare_builtin("__cmpflt64",INT,DOUBLE,0,DOUBLE,0,1,0);
1641
 
1642
 
1643
  return 1;
1644
}
1645
 
1646
int freturn(struct Typ *t)
1647
/*  Returns the register in which variables of type t are returned. */
1648
/*  If the value cannot be returned in a register returns 0.        */
1649
{
1650
  int f=t->flags&NQ;
1651
  if(ISSCALAR(f)){
1652
    if(ISHWORD(f)||f==CHAR)
1653
      return acc;
1654
    else if(ISLWORD(f))
1655
      return dx;
1656
  }
1657
  return 0;
1658
}
1659
 
1660
int regok(int r,int t,int mode)
1661
/*  Returns 0 if register r cannot store variables of   */
1662
/*  type t. If t==POINTER and mode!=0 then it returns   */
1663
/*  non-zero only if the register can store a pointer   */
1664
/*  and dereference a pointer to mode.                  */
1665
{
1666
  if(!ISSCALAR(t)) return 0;
1667
  if(r==dx){
1668
    if(ISLWORD(t)&&(optflags&2)&&!nodx) return 1;
1669
    return 0;
1670
  }
1671
  if(mode==-1){
1672
    if(ISHWORD(t)) return 1;
1673
    if((t&NQ)==CHAR&&ISACC(r)) return 1;
1674
  }else{
1675
    if(ISIDX(r)){
1676
      if(ISPOINTER(t)&&ISHWORD(t))
1677
        return 1;
1678
    }
1679
    if(ISACC(r)){
1680
      if((t&NQ)==CHAR)
1681
        return 1;
1682
      if(ISINT(t)&&ISHWORD(t))
1683
        return 1;
1684
    }
1685
  }
1686
  return 0;
1687
}
1688
 
1689
int reg_pair(int r,struct rpair *p)
1690
/* Returns 0 if the register is no register pair. If r  */
1691
/* is a register pair non-zero will be returned and the */
1692
/* structure pointed to p will be filled with the two   */
1693
/* elements.                                            */
1694
{
1695
  if(r==dx){
1696
    p->r1=acc;
1697
    p->r2=ix;
1698
    return 1;
1699
  }
1700
  return 0;
1701
}
1702
 
1703
int cost_savings(struct IC *p,int r,struct obj *o)
1704
{
1705
  /*FIXME*/
1706
  int c=p->code;
1707
  if(r==dx){
1708
    if(c==GETRETURN||c==SETRETURN||c==PUSH||c==ASSIGN) return 8;
1709
    return INT_MIN;
1710
  }
1711
  if(o->flags&VKONST){
1712
    struct obj *co=&o->v->cobj;
1713
    if(o->flags&DREFOBJ)
1714
      return 0;
1715
    if(o==&p->q1&&p->code==ASSIGN&&((p->z.flags&DREFOBJ)||p->z.v->storage_class==STATIC||p->z.v->storage_class==EXTERN)){
1716
      return 2;
1717
    }
1718
    return 0;
1719
  }
1720
  if((o->flags&DREFOBJ)){
1721
    if(!ISIDX(r)) return INT_MIN;
1722
    if(p->q2.flags&&o!=&p->z)
1723
      return 6;
1724
    else
1725
      return 6;
1726
  }else if(c==GETRETURN&&p->q1.reg==r){
1727
    return 4;
1728
  }else if(c==SETRETURN&&p->z.reg==r){
1729
    return 4;
1730
  }else if(c==CONVERT&&((p->typf&NQ)==CHAR||(p->typf2&NQ)==CHAR)&&regok(r,CHAR,0)){
1731
    return 3;
1732
  }
1733
  if(o==&p->z&&r==acc){
1734
    if(c==SUB||c==SUBIFP||c==SUBPFP||c==AND||c==OR||c==XOR)
1735
      return 6;
1736
    if((c==ADD||c==ADDI2P)&&!(p->q1.flags&(KONST|VKONST))&&!(p->q2.flags&(KONST|VKONST)))
1737
      return 4;
1738
    if(c==MULT) return 5;
1739
    if(c==ASSIGN&&(p->q1.flags&KONST)){
1740
      eval_const(&p->q1.val,p->typf);
1741
      if(zmeqto(vmax,l2zm(0L))&&zumeqto(vumax,ul2zum(0UL)))
1742
        return 3;
1743
    }
1744
  }
1745
#if 1
1746
  if((o==&p->q2/*||o==&p->z*/)&&!(o->flags&DREFOBJ)&&!ISACC(o->reg)&&(c==MULT||c==DIV||c==MOD))
1747
    return INT_MIN;
1748
#endif
1749
  if(c==COMPARE||c==TEST){
1750
    if(r==ix) return 3;
1751
    if(r==iy) return 2;
1752
    if(r==iu) return 1;
1753
  }
1754
  return 2;
1755
}
1756
 
1757
int dangerous_IC(struct IC *p)
1758
/*  Returns zero if the IC p can be safely executed     */
1759
/*  without danger of exceptions or similar things.     */
1760
/*  vbcc may generate code in which non-dangerous ICs   */
1761
/*  are sometimes executed although control-flow may    */
1762
/*  never reach them (mainly when moving computations   */
1763
/*  out of loops).                                      */
1764
/*  Typical ICs that generate exceptions on some        */
1765
/*  machines are:                                       */
1766
/*      - accesses via pointers                         */
1767
/*      - division/modulo                               */
1768
/*      - overflow on signed integer/floats             */
1769
{
1770
  int c=p->code;
1771
  if((p->q1.flags&DREFOBJ)||(p->q2.flags&DREFOBJ)||(p->z.flags&DREFOBJ))
1772
    return 1;
1773
  if((c==DIV||c==MOD)&&!isconst(q2))
1774
    return 1;
1775
  return 0;
1776
}
1777
 
1778
/* Return name of library function, if this node should be
1779
   implemented via libcall. */
1780
char *use_libcall(int c,int t,int t2)
1781
{
1782
  static char fname[16];
1783
  char *ret=0;
1784
 
1785
  if(c==COMPARE){
1786
    if((t&NQ)==LLONG||ISFLOAT(t)){
1787
      sprintf(fname,"__cmp%s%s%ld",(t&UNSIGNED)?"u":"s",ISFLOAT(t)?"flt":"int",zm2l(sizetab[t&NQ])*8);
1788
      ret=fname;
1789
    }
1790
  }else{
1791
    t&=NU;
1792
    t2&=NU;
1793
    if(t==LDOUBLE) t=DOUBLE;
1794
    if(t2==LDOUBLE) t2=DOUBLE;
1795
    if(c==CONVERT){
1796
      if(t==t2) return 0;
1797
      if(t==FLOAT&&t2==DOUBLE) return "__flt64toflt32";
1798
      if(t==DOUBLE&&t2==FLOAT) return "__flt32toflt64";
1799
 
1800
      if(ISFLOAT(t)){
1801
        sprintf(fname,"__%cint%ldtoflt%d",(t2&UNSIGNED)?'u':'s',zm2l(sizetab[t2&NQ])*8,(t==FLOAT)?32:64);
1802
        ret=fname;
1803
      }
1804
      if(ISFLOAT(t2)){
1805
        sprintf(fname,"__flt%dto%cint%ld",((t2&NU)==FLOAT)?32:64,(t&UNSIGNED)?'u':'s',zm2l(sizetab[t&NQ])*8);
1806
        ret=fname;
1807
      }
1808
    }
1809
    if((t&NQ)==LLONG||ISFLOAT(t)){
1810
      if((c>=LSHIFT&&c<=MOD)||(c>=OR&&c<=AND)||c==KOMPLEMENT||c==MINUS){
1811
        if(t==(UNSIGNED|LLONG)&&(c==DIV||c==MOD||c==RSHIFT)){
1812
          sprintf(fname,"__%suint64",ename[c]);
1813
          ret=fname;
1814
        }else if((t&NQ)==LLONG){
1815
          sprintf(fname,"__%sint64",ename[c]);
1816
          ret=fname;
1817
        }else if(t==(UNSIGNED|LONG)&&(c==DIV||c==MOD||c==RSHIFT)){
1818
          sprintf(fname,"__%suint32",ename[c]);
1819
          ret=fname;
1820
        }else if((t&NQ)==LONG){
1821
          sprintf(fname,"__%sint32",ename[c]);
1822
          ret=fname;
1823
        }else{
1824
          sprintf(fname,"__%s%s%s%ld",ename[c],(c!=MULT&&(t&UNSIGNED))?"u":"",ISFLOAT(t)?"flt":"int",zm2l(sizetab[t&NQ])*8);
1825
          ret=fname;
1826
        }
1827
      }
1828
    }
1829
    if((c==MULT&&(CPU==6809||(t&NQ)==LONG))||c==DIV||c==MOD){
1830
      sprintf(fname,"__%s%s%s%ld",ename[c],(c!=MULT&&(t&UNSIGNED))?"u":"",ISFLOAT(t)?"flt":"int",zm2l(sizetab[t&NQ])*8);
1831
      ret=fname;
1832
    }
1833
  }
1834
 
1835
  return ret;
1836
}
1837
 
1838
 
1839
 
1840
int must_convert(int o,int t,int const_expr)
1841
/*  Returns zero if code for converting np to type t    */
1842
/*  can be omitted.                                     */
1843
{
1844
  int op=o&NQ,tp=t&NQ;
1845
  if(op==tp) return 0;
1846
  if(ISHWORD(op)&&ISHWORD(tp)) return 0;
1847
  if(ISFLOAT(op)||ISFLOAT(tp)) return 1;
1848
  if(ISLWORD(op)&&ISLWORD(tp)) return 0;
1849
  return 1;
1850
}
1851
 
1852
void gen_ds(FILE *f,zmax size,struct Typ *t)
1853
/*  This function has to create <size> bytes of storage */
1854
/*  initialized with zero.                              */
1855
{
1856
  if(newobj&&section!=SPECIAL)
1857
    emit(f,"%ld\n",zm2l(size));
1858
  else
1859
    emit(f,"\t.space\t%ld\n",zm2l(size));
1860
  newobj=0;
1861
}
1862
 
1863
void gen_align(FILE *f,zmax align)
1864
/*  This function has to make sure the next data is     */
1865
/*  aligned to multiples of <align> bytes.              */
1866
{
1867
  /* nothing to do */
1868
}
1869
 
1870
void gen_var_head(FILE *f,struct Var *v)
1871
/*  This function has to create the head of a variable  */
1872
/*  definition, i.e. the label and information for      */
1873
/*  linkage etc.                                        */
1874
{
1875
  int constflag;
1876
  if(v->clist) constflag=is_const(v->vtyp);
1877
  if(v->storage_class==STATIC){
1878
    if(ISFUNC(v->vtyp->flags)) return;
1879
    if(v->tattr&DPAGE)
1880
      emit(f,"\t.direct\t%s%ld\n",labprefix,zm2l(v->offset));
1881
    if(!special_section(f,v)){
1882
      if(v->clist&&(!constflag||(g_flags[3]&USEDFLAG))&&section!=DATA){
1883
        emit(f,dataname);if(f) section=DATA;
1884
      }
1885
      if(v->clist&&constflag&&!(g_flags[3]&USEDFLAG)&&section!=RODATA){
1886
        emit(f,rodataname);if(f) section=RODATA;
1887
      }
1888
      if(!v->clist&&section!=BSS){
1889
        emit(f,bssname);if(f) section=BSS;
1890
      }
1891
    }
1892
    emit(f,"\t.type\t%s%ld,@object\n",labprefix,zm2l(v->offset));
1893
    emit(f,"\t.size\t%s%ld,%ld\n",labprefix,zm2l(v->offset),zm2l(szof(v->vtyp)));
1894
    if(v->clist||section==SPECIAL)
1895
      emit(f,"%s%ld:\n",labprefix,zm2l(v->offset));
1896
    else
1897
      emit(f,"\t.lcomm\t%s%ld,",labprefix,zm2l(v->offset));
1898
    newobj=1;
1899
  }
1900
  if(v->storage_class==EXTERN){
1901
    if(v->flags&(DEFINED|TENTATIVE)){
1902
      emit(f,"\t.global\t%s%s\n",idprefix,v->identifier);
1903
      if(v->tattr&DPAGE)
1904
        emit(f,"\t.direct\t%s%s\n",idprefix,v->identifier);
1905
      if(!special_section(f,v)){
1906
        if(v->clist&&(!constflag||(g_flags[3]&USEDFLAG))&&section!=DATA){
1907
          emit(f,dataname);if(f) section=DATA;
1908
        }
1909
        if(v->clist&&constflag&&!(g_flags[3]&USEDFLAG)&&section!=RODATA){
1910
          emit(f,rodataname);if(f) section=RODATA;
1911
        }
1912
        if(!v->clist&&section!=BSS){
1913
          emit(f,bssname);if(f) section=BSS;
1914
        }
1915
      }
1916
      emit(f,"\t.type\t%s%s,@object\n",idprefix,v->identifier);
1917
      emit(f,"\t.size\t%s%s,%ld\n",idprefix,v->identifier,zm2l(szof(v->vtyp)));
1918
      if(v->clist||section==SPECIAL)
1919
        emit(f,"%s%s:\n",idprefix,v->identifier);
1920
      else
1921
        emit(f,"\t.global\t%s%s\n\t.lcomm\t%s%s,",idprefix,v->identifier,idprefix,v->identifier);
1922
      newobj=1;
1923
    }
1924
  }
1925
}
1926
 
1927
void gen_dc(FILE *f,int t,struct const_list *p)
1928
/*  This function has to create static storage          */
1929
/*  initialized with const-list p.                      */
1930
{
1931
  emit(f,"\t%s\t",dct[t&NQ]);
1932
  if(!p->tree){
1933
    if(ISFLOAT(t)){
1934
      /*  auch wieder nicht sehr schoen und IEEE noetig   */
1935
      unsigned char *ip;
1936
      ip=(unsigned char *)&p->val.vdouble;
1937
      emit(f,"0x%02x%02x%02x%02x",ip[3],ip[2],ip[1],ip[0]);
1938
      if((t&NQ)==DOUBLE||(t&NQ)==LDOUBLE){
1939
        emit(f,",0x%02x%02x%02x%02x",ip[7],ip[6],ip[5],ip[4]);
1940
      }
1941
    }else{
1942
      emitval(f,&p->val,(t&NU)|UNSIGNED);
1943
    }
1944
  }else{
1945
    int m=p->tree->o.flags,md=drel,mp=pcrel;
1946
    p->tree->o.flags&=~VARADR;
1947
    drel=0;pcrel=0;
1948
    emit_obj(f,&p->tree->o,t&NU);
1949
    p->tree->o.flags=m;
1950
    drel=md;pcrel=mp;
1951
  }
1952
  emit(f,"\n");newobj=0;
1953
}
1954
 
1955
 
1956
static void preload(FILE *f,IC *p)
1957
{
1958
  int t,r;
1959
 
1960
  if((p->typf&VOLATILE)||(p->typf2&VOLATILE)||
1961
     ((p->q1.flags&DREFOBJ)&&(p->q1.dtyp&(VOLATILE|PVOLATILE)))||
1962
     ((p->q2.flags&DREFOBJ)&&(p->q2.dtyp&(VOLATILE|PVOLATILE)))||
1963
     ((p->z.flags&DREFOBJ)&&(p->z.dtyp&(VOLATILE|PVOLATILE))))
1964
    emit(f,"; volatile barrier\n");
1965
 
1966
  t=q1typ(p);
1967
  if(!p->q1.am&&(p->q1.flags&(REG|DREFOBJ|KONST))==DREFOBJ&&ISLWORD(t)){
1968
    r=get_idx(f,p);
1969
    p->q1.flags&=~DREFOBJ;
1970
    load_reg(f,r,&p->q1,INT);
1971
    p->q1.flags|=(REG|DREFOBJ);
1972
    p->q1.reg=r;
1973
  }
1974
  t=q2typ(p);
1975
  if(!p->q2.am&&(p->q2.flags&(REG|DREFOBJ|KONST))==DREFOBJ&&ISLWORD(t)){
1976
    r=get_idx(f,p);
1977
    p->q2.flags&=~DREFOBJ;
1978
    load_reg(f,r,&p->q2,INT);
1979
    p->q2.flags|=(REG|DREFOBJ);
1980
    p->q2.reg=r;
1981
  }else if(isreg(z)&&(((p->q2.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p->q2.reg==p->z.reg)||(p->q2.am&&p->q2.am->base==p->z.reg))){
1982
    r=get_idx(f,p);
1983
    p->q2.flags&=~DREFOBJ;
1984
    load_reg(f,r,&p->q2,INT);
1985
    p->q2.flags|=(REG|DREFOBJ);
1986
    p->q2.reg=r;
1987
  }
1988
  t=ztyp(p);
1989
  if(!p->z.am&&(p->z.flags&(REG|DREFOBJ|KONST))==DREFOBJ&&ISLWORD(t)){
1990
    r=get_idx(f,p);
1991
    p->z .flags&=~DREFOBJ;
1992
    load_reg(f,r,&p->z ,INT);
1993
    p->z .flags|=(REG|DREFOBJ);
1994
    p->z .reg=r;
1995
  }
1996
}
1997
 
1998
/*  The main code-generation routine.                   */
1999
/*  f is the stream the code should be written to.      */
2000
/*  p is a pointer to a doubly linked list of ICs       */
2001
/*  containing the function body to generate code for.  */
2002
/*  v is a pointer to the function.                     */
2003
/*  offset is the size of the stackframe the function   */
2004
/*  needs for local variables.                          */
2005
void gen_code(FILE *f,struct IC *fp,struct Var *v,zmax offset)
2006
{
2007
  int c,t,lastcomp=0,reg,short_add,bit_reverse,need_return=0;
2008
  struct obj *bit_obj;char *bit_reg;
2009
  static int idone;
2010
  struct obj o;
2011
  IC *p,*p2;
2012
  if(v->tattr&INTERRUPT)
2013
    ret="rti";
2014
  else if (v->tattr&FAR)
2015
        ret="rtf";
2016
  else
2017
    ret="rts"; /*FIXME: banked */
2018
  if(DEBUG&1) printf("gen_code()\n");
2019
  for(p=fp;p;p=p->next) clear_ext_ic(&p->ext);
2020
  emit(f,"#off1=%ld\n",zm2l(offset));
2021
  if(!(g_flags[5]&USEDFLAG)){
2022
    peephole(fp);
2023
    if(!frame_used) offset=l2zm(0L);
2024
  }
2025
  for(c=1;c<=MAXR;c++) regs[c]=(regsa[c]==REGSA_NEVER)?1:0;
2026
  for(c=1;c<=MAXR;c++){
2027
    if(regscratch[c]&&(regsa[c]||regused[c])){
2028
      BSET(regs_modified,c);
2029
    }
2030
  }
2031
  t=0;
2032
  for(p=fp;p;p=p->next){
2033
    c=p->code;
2034
    if(c==ALLOCREG){ regs[p->q1.reg]=1; if(p->q1.reg==dx) regs[acc]=regs[ix]=1;}
2035
    if(c==FREEREG){ regs[p->q1.reg]=0; if(p->q1.reg==dx) regs[acc]=regs[ix]=0;}
2036
    if((c==LSHIFT||c==RSHIFT)&&(p->typf&NQ)>=LONG) regused[iy]=1;
2037
    if(c==PUSH&&(p->q1.flags&(REG|DREFOBJ))!=REG){
2038
      if(zmeqto(p->q2.val.vmax,Z1)){
2039
        if(regs[acc]) t=(t>2)?t:2;
2040
      }else if(zmeqto(p->q2.val.vmax,l2zm(2L))){
2041
        if(regs[acc]&&regs[ix]&&regs[iy]&&(CPU==6812||regs[iu])) t=(t>2)?t:2;
2042
      }else if(zmeqto(p->q2.val.vmax,l2zm(4L))){
2043
        if(regs[acc]) t=(t>2)?t:2;
2044
      }else{
2045
        /* TODO: finer check */
2046
        if(drel||!regsa[iu])
2047
          t=(t>8)?t:8;
2048
        else
2049
          t=(t>6)?t:6;
2050
      }
2051
    }
2052
  }
2053
  emit(f,"#toff=%d\n",t);
2054
  loff=zm2l(offset)+t;
2055
  function_top(f,v,loff);
2056
  stackoffset=notpopped=dontpop=maxpushed=0;
2057
  for(p=fp;p;pr(f,p),p=p->next){
2058
    c=p->code;t=p->typf;
2059
    if(debug_info)
2060
      dwarf2_line_info(f,p);
2061
    short_add=0;
2062
    if(c==NOP) continue;
2063
    if(c==ALLOCREG){
2064
      regs[p->q1.reg]=1;
2065
      if(p->q1.reg==dx) regs[acc]=regs[ix]=1;
2066
      continue;
2067
    }
2068
    if(c==FREEREG){
2069
      regs[p->q1.reg]=0;
2070
      if(p->q1.reg==dx) regs[acc]=regs[ix]=0;
2071
      continue;
2072
    }
2073
    if(notpopped&&!dontpop){
2074
      int flag=0;
2075
      if(c==LABEL||c==COMPARE||c==TEST||c==BRA){
2076
        gen_pop(f,notpopped);
2077
        notpopped=0;
2078
      }
2079
    }
2080
    if(c==LABEL) {cc=0;emit(f,"%s%d:\n",labprefix,t);continue;}
2081
    if(c>=BEQ&&c<=BGT&&t==exit_label) need_return=1;
2082
    if(c==BRA){
2083
      if(p->typf==exit_label&&!have_frame){
2084
        emit(f,"\t%s\n",ret);
2085
      }else{
2086
        if(t==exit_label) need_return=1;
2087
        emit(f,"\tbra\t%s%d\n",labprefix,t);
2088
      }
2089
      cc=0;continue;
2090
    }
2091
    if(c>=BEQ&&c<BRA){
2092
      if((lastcomp&UNSIGNED)||ISPOINTER(lastcomp))
2093
        emit(f,"\tb%s\t%s%d\n",uccs[c-BEQ],labprefix,t);
2094
      else
2095
        emit(f,"\tb%s\t%s%d\n",ccs[c-BEQ],labprefix,t);
2096
      continue;
2097
    }
2098
    if(c==MOVETOREG){
2099
      load_reg(f,p->z.reg,&p->q1,SHORT);
2100
      continue;
2101
    }
2102
    if(c==MOVEFROMREG){
2103
      store_reg(f,p->q1.reg,&p->z,SHORT);
2104
      continue;
2105
    }
2106
 
2107
    /*if(ISFLOAT(t)) {pric2(stdout,p);ierror(0);}*/
2108
 
2109
    if((t&NQ)==BIT){
2110
      ierror(0);
2111
    }
2112
 
2113
    if(c==CONVERT&&ISLWORD(t)&&ISLWORD(p->typf2)){
2114
      p->code=c=ASSIGN;
2115
      p->q2.val.vmax=l2zm(4L);
2116
    }
2117
 
2118
    if((p->q2.flags&REG)&&ISACC(p->q2.reg)&&(c==ADD||c==MULT||c==AND||c==OR||c==XOR)){
2119
      obj o=p->q1;
2120
      p->q1=p->q2;
2121
      p->q2=o;
2122
    }
2123
 
2124
    if(c==TEST){
2125
      lastcomp=t;
2126
      p->code=c=COMPARE;
2127
      gval.vmax=l2zm(0L);
2128
      p->q2.flags=KONST;
2129
      eval_const(&gval,MAXINT);
2130
      insert_const(&p->q2.val,t);
2131
    }
2132
 
2133
    if(c==SUBPFP){
2134
      p->code=c=SUB;
2135
      p->typf=t=(UNSIGNED|INT);
2136
    }
2137
 
2138
 
2139
 
2140
    if((c==ASSIGN||c==PUSH)&&zmeqto(p->q2.val.vmax,l2zm(4L)))
2141
      p->typf=t=LONG;
2142
 
2143
    preload(f,p);
2144
 
2145
    if(c==ADDI2P||c==SUBIFP){
2146
      if((p->typf2&NQ)!=HPOINTER){
2147
        if(p->q2.flags&KONST){
2148
          eval_const(&p->q2.val,p->typf);
2149
          insert_const(&p->q2.val,p->typf2);
2150
          p->typf=t=(UNSIGNED|SHORT);
2151
        }else{
2152
          if(ISLWORD(t)) inc_addr(&p->q2,2,t);
2153
          if((t&NQ)==CHAR) short_add=t;
2154
          p->typf=t=(UNSIGNED|SHORT);
2155
        }
2156
      }else if(ISHWORD(t)){
2157
        if((t&NQ)==LLONG)
2158
          inc_addr(&p->q2,4,t);
2159
        else if((t&NQ)!=LONG)
2160
          short_add=t;
2161
        p->typf=t=(UNSIGNED|LONG);
2162
      }
2163
      p->code=c=(c==ADDI2P)?ADD:SUB;
2164
    }
2165
 
2166
    if(c==COMPARE&&ISLWORD(t)){
2167
      IC *branch=p->next;
2168
      int r;
2169
      while(branch&&branch->code==FREEREG) branch=branch->next;
2170
      if(!branch) ierror(0);
2171
      c=branch->code;
2172
      if(c<BEQ||c>BGT) ierror(0);
2173
      if(!regs[ix])
2174
        r=ix;
2175
      else
2176
        r=get_reg(f,p,INT);
2177
 
2178
      if(c==BEQ||c==BNE){
2179
        inc_addr(&p->q1,0,t);
2180
        inc_addr(&p->q2,0,t);
2181
        load_reg(f,r,&p->q1,INT);
2182
        emit(f,"\t%s%s\t",CPU==6812?"cp":"cmp",regnames[r]);
2183
        emit_obj(f,&p->q2,INT);
2184
        emit(f,"\n");
2185
        if(pushed_acc) emit(f,SPULLD);
2186
        emit(f,"\tbne\t%s%d\n",labprefix,c==BEQ?++label:branch->typf);
2187
        if(pushed_acc) emit(f,SPUSHD);
2188
        inc_addr(&p->q1,2,t);
2189
        inc_addr(&p->q2,2,t);
2190
        load_reg(f,r,&p->q1,INT);
2191
        emit(f,"\t%s%s\t",CPU==6812?"cp":"cmp",regnames[r]);
2192
        emit_obj(f,&p->q2,INT);
2193
        emit(f,"\n");
2194
        pr(f,p);
2195
        if(c==BEQ){
2196
          emit(f,"\tbeq\t%s%d\n",labprefix,branch->typf);
2197
          emit(f,"%s%d:\n",labprefix,label);
2198
        }else
2199
          emit(f,"\tbne\t%s%d\n",labprefix,branch->typf);
2200
      }else{
2201
        inc_addr(&p->q1,0,t);
2202
        inc_addr(&p->q2,0,t);
2203
        load_reg(f,r,&p->q1,INT);
2204
        emit(f,"\t%s%s\t",CPU==6812?"cp":"cmp",regnames[r]);
2205
        emit_obj(f,&p->q2,INT);
2206
        emit(f,"\n");
2207
        label++;
2208
        if(pushed_acc) emit(f,SPULLD);
2209
        if(t&UNSIGNED){
2210
          if(c==BLT||c==BGT)
2211
            emit(f,"\tb%s\t%s%d\n",(c==BLT)?"lo":"hi",labprefix,branch->typf);
2212
          else
2213
            emit(f,"\tb%s\t%s%d\n",(c==BGE)?"lo":"hi",labprefix,label);
2214
        }else{
2215
          if(c==BLT||c==BGT)
2216
            emit(f,"\tb%s\t%s%d\n",(c==BLT)?"lt":"gt",labprefix,branch->typf);
2217
          else
2218
            emit(f,"\tb%s\t%s%d\n",(c==BGE)?"lt":"gt",labprefix,label);
2219
        }
2220
        emit(f,"\tbne\t%s%d\n",labprefix,(c==BLT||c==BGT)?label:branch->typf);
2221
        if(pushed_acc) emit(f,SPUSHD);
2222
        inc_addr(&p->q1,2,t);
2223
        inc_addr(&p->q2,2,t);
2224
        load_reg(f,r,&p->q1,INT);
2225
        emit(f,"\t%s%s\t",CPU==6812?"cp":"cmp",regnames[r]);
2226
        emit_obj(f,&p->q2,INT);
2227
        emit(f,"\n");
2228
        pr(f,p);
2229
        emit(f,"\tb%s\t%s%d\n",uccs[c-BEQ],labprefix,branch->typf);
2230
        emit(f,"%s%d:\n",labprefix,label);
2231
      }
2232
      branch->code=NOP;
2233
      continue;
2234
    }
2235
 
2236
    if(ISLWORD(t)&&(c==LSHIFT||c==RSHIFT)){
2237
      int cnt=-1000,i,r=0;
2238
      int px=0,py=0,pa=0;
2239
      if(isconst(q2)){
2240
        eval_const(&p->q2.val,p->typf2);
2241
        cnt=(int)zm2l(vmax);
2242
        if(cnt==1&&compare_objects(&p->q1,&p->z)){
2243
          if(c==LSHIFT)
2244
            emit(f,"\tlsl\t");
2245
          else
2246
            emit(f,"\t%s\t",(t&UNSIGNED)?"lsr":"asr");
2247
          inc_addr(&p->z,c==LSHIFT?3:0,t);
2248
          emit_obj(f,&p->z,t);
2249
          emit(f,"\n");
2250
          emit(f,"\t%s\t",(c==LSHIFT)?"rol":"ror");
2251
          inc_addr(&p->z,c==LSHIFT?-1:1,t);
2252
          emit_obj(f,&p->z,t);
2253
          emit(f,"\n");
2254
          emit(f,"\t%s\t",(c==LSHIFT)?"rol":"ror");
2255
          inc_addr(&p->z,c==LSHIFT?-1:1,t);
2256
          emit_obj(f,&p->z,t);
2257
          emit(f,"\n");
2258
          emit(f,"\t%s\t",(c==LSHIFT)?"rol":"ror");
2259
          inc_addr(&p->z,c==LSHIFT?-1:1,t);
2260
          emit_obj(f,&p->z,t);
2261
          emit(f,"\n");
2262
          continue;
2263
        }
2264
      }
2265
      inc_addr(&p->q1,2,t);
2266
      inc_addr(&p->z,2,t);
2267
 
2268
      if(ISRACC(q2)||(regs[acc]&&!scratchreg(acc,p))){
2269
        emit(f,SPUSHD);
2270
        push(2);
2271
        pa=1;
2272
      }
2273
 
2274
      if(cnt<0||(optsize&&cnt>1)||(cnt>3&&!optspeed)){
2275
        if(regs[ix]&&!scratchreg(ix,p)) {px=1;emit(f,SPUSH("x"));push(2);}
2276
        if(regs[iy]&&!scratchreg(iy,p)) {py=1;emit(f,SPUSH("y"));push(2);}
2277
      }
2278
 
2279
      if(!compare_objects(&p->q1,&p->z)){
2280
        load_reg(f,acc,&p->q1,INT);
2281
        store_reg(f,acc,&p->z,INT);
2282
      }
2283
      inc_addr(&p->q1,-2,t);
2284
      inc_addr(&p->z,-2,t);
2285
      load_reg(f,acc,&p->q1,INT);
2286
      if(cnt<0||(optsize&&cnt>1)||(cnt>3&&!optspeed)){
2287
        if((p->q2.flags&REG)&&p->q2.reg==ix){
2288
          if((p->z.flags&REG)&&p->z.reg==iy) ierror(0);
2289
        }else
2290
          load_addr(f,ix,&p->z);
2291
        if(ISRACC(q2)){
2292
          if(scratchreg(acc,p)&&(px+py==0)){
2293
            emit(f,SPULL("y"));
2294
            pop(2);pa=0;
2295
          }else
2296
            emit(f,"\tldy\t%d,%s\n",(px+py)*2,regnames[sp]);
2297
        }else
2298
          load_reg(f,iy,&p->q2,p->typf2); /*TODO: types!=INT?? */
2299
        if((p->q2.flags&REG)&&p->q2.reg==ix)
2300
          load_addr(f,ix,&p->z);
2301
        if(c==LSHIFT)
2302
          emit(f,"\t%s\t%s__lsll\n",jsrinst,idprefix);
2303
        else
2304
          emit(f,"\t%s\t%s__%s\n",jsrinst,idprefix,(t&UNSIGNED)?"lsrl":"asrl");
2305
        if(py) {emit(f,SPULL("y"));pop(2);}
2306
        if(px) {emit(f,SPULL("x"));pop(2);}
2307
      }else{
2308
        inc_addr(&p->z,c==LSHIFT?3:2,t);
2309
        for(i=0;i<cnt;i++){
2310
          if(c==LSHIFT){
2311
            emit(f,"\tlsl\t");
2312
            emit_obj(f,&p->z,CHAR);
2313
            emit(f,"\n");
2314
            inc_addr(&p->z,-1,t);
2315
            emit(f,"\trol\t");
2316
            emit_obj(f,&p->z,CHAR);
2317
            emit(f,"\n");
2318
            inc_addr(&p->z,1,t);
2319
            emit(f,"\trolb\n");
2320
            emit(f,"\trola\n");
2321
          }else{
2322
            emit(f,"\t%s\n",(t&UNSIGNED)?"lsra":"asra");
2323
            emit(f,"\trorb\n");
2324
            emit(f,"\tror\t");
2325
            emit_obj(f,&p->z,CHAR);
2326
            emit(f,"\n");
2327
            inc_addr(&p->z,1,t);
2328
            emit(f,"\tror\t");
2329
            emit_obj(f,&p->z,CHAR);
2330
            emit(f,"\n");
2331
            inc_addr(&p->z,-1,t);
2332
          }
2333
        }
2334
        inc_addr(&p->z,c==LSHIFT?-3:-2,t);
2335
        store_reg(f,acc,&p->z,INT);
2336
      }
2337
      if(pa) {emit(f,SPULLD);pop(2);}
2338
      continue;
2339
    }
2340
 
2341
    if(ISLWORD(t)&&c!=GETRETURN&&c!=SETRETURN&&c!=COMPARE&&c!=CONVERT&&c!=ADDRESS){
2342
      if(c==PUSH&&isreg(q1)&&p->q1.reg==dx){
2343
        if(CPU==6812){
2344
          emit(f,"\tpshd\n");
2345
          emit(f,"\tpshx\n");
2346
        }else{
2347
          //emit(f,"\tpshs\ta,b,x\n");
2348
          emit(f,"\tpshs\tb,a\n");
2349
          emit(f,"\tpshs\tx\n");
2350
        }
2351
        push(4);
2352
        continue;
2353
      }
2354
      if(c==ASSIGN&&isreg(q1)&&p->q1.reg==dx){
2355
        inc_addr(&p->z,2,t);
2356
        store_reg(f,ix,&p->z,INT);
2357
        inc_addr(&p->z,-2,t);
2358
        store_reg(f,acc,&p->z,INT);
2359
        continue;
2360
      }
2361
      if(c==ASSIGN&&isreg(z)&&p->z.reg==dx){
2362
        inc_addr(&p->q1,2,t);
2363
        load_reg(f,ix,&p->q1,INT);
2364
        inc_addr(&p->q1,-2,t);
2365
        load_reg(f,acc,&p->q1,INT);
2366
        continue;
2367
      }
2368
      if(c==PUSH){
2369
        if(regs[acc]) emit(f,"\tstd\t%ld,%s\n",loff-roff-2-stackoffset,regnames[sp]);
2370
      }else
2371
        get_acc(f,p);
2372
      /*TODO: acc in IC, constants */
2373
      inc_addr(&p->q1,2,t);
2374
      if(c==MINUS){
2375
        if(CPU!=6812&&!optsize)
2376
          emit(f,"\tldd\t#0\n");
2377
        else
2378
          emit(f,"\tclra\n\tclrb\n");
2379
      }else
2380
        load_reg(f,acc,&p->q1,INT);
2381
      if(c==ADD||c==SUB){
2382
        inc_addr(&p->q2,2,t);
2383
        emit(f,"\t%s\t",c==ADD?"addd":"subd");
2384
        emit_obj(f,&p->q2,INT);
2385
        emit(f,"\n");
2386
      }else if(c==ASSIGN||c==PUSH){
2387
      }else if(c==MINUS){
2388
        emit(f,"\tsubd\t");
2389
        emit_obj(f,&p->q1,INT);
2390
        emit(f,"\n");
2391
      }else if(c==KOMPLEMENT){
2392
        emit(f,"\tcoma\n");
2393
        emit(f,"\tcomb\n");
2394
      }else{
2395
        if(c==AND)
2396
          emit(f,"\tandb\t");
2397
        else if(c==OR)
2398
          emit(f,"\tor%sb\t",CPU==6812?"a":"");
2399
        else if(c==XOR)
2400
          emit(f,"\teorb\t");
2401
        inc_addr(&p->q2,3,t);
2402
        emit_obj(f,&p->q2,CHAR);
2403
        emit(f,"\n");
2404
        if(c==AND)
2405
          emit(f,"\tanda\t");
2406
        else if(c==OR)
2407
          emit(f,"\tor%sa\t",CPU==6812?"a":"");
2408
        else if(c==XOR)
2409
          emit(f,"\teora\t");
2410
        inc_addr(&p->q2,-1,t);
2411
        emit_obj(f,&p->q2,CHAR);
2412
        emit(f,"\n");
2413
      }
2414
      if(c==PUSH){
2415
        if(CPU==6812)
2416
          emit(f,"\tpshd\n");
2417
        else
2418
          emit(f,"\tpshs\tb,a\n");
2419
        push(2);dontpop+=2;
2420
      }else{
2421
        inc_addr(&p->z,2,t);
2422
        store_reg(f,acc,&p->z,INT);
2423
      }
2424
      inc_addr(&p->q1,-2,t);
2425
      if(c==MINUS)
2426
        emit(f,"\tldd\t#0\n");
2427
      else
2428
        load_reg(f,acc,&p->q1,INT);
2429
      if(c==ADD)
2430
        emit(f,"\tadcb\t");
2431
      else if(c==SUB)
2432
        emit(f,"\tsbcb\t");
2433
      else if(c==AND)
2434
        emit(f,"\tandb\t");
2435
      else if(c==OR)
2436
        emit(f,"\tor%sb\t",CPU==6812?"a":"");
2437
      else if(c==XOR)
2438
        emit(f,"\teorb\t");
2439
      else if(c==KOMPLEMENT)
2440
        emit(f,"\tcomb\n");
2441
      else if(c==MINUS){
2442
        inc_addr(&p->q1,1,t);
2443
        emit(f,"\tsbcb\t");
2444
        emit_obj(f,&p->q1,CHAR);
2445
        emit(f,"\n");
2446
      }
2447
      if(p->q2.flags){
2448
        inc_addr(&p->q2,-1,t);
2449
        emit_obj(f,&p->q2,CHAR);
2450
        emit(f,"\n");
2451
      }
2452
      if(c==ADD)
2453
        emit(f,"\tadca\t");
2454
      else if(c==SUB)
2455
        emit(f,"\tsbca\t");
2456
      else if(c==AND)
2457
        emit(f,"\tanda\t");
2458
      else if(c==OR)
2459
        emit(f,"\tor%sa\t",CPU==6812?"a":"");
2460
      else if(c==XOR)
2461
        emit(f,"\teora\t");
2462
      else if(c==KOMPLEMENT)
2463
        emit(f,"\tcoma\n");
2464
      else if(c==MINUS){
2465
        inc_addr(&p->q1,-1,t);
2466
        emit(f,"\tsbca\t");
2467
        emit_obj(f,&p->q1,CHAR);
2468
        emit(f,"\n");
2469
      }
2470
      if(p->q2.flags){
2471
        inc_addr(&p->q2,-1,t);
2472
        emit_obj(f,&p->q2,CHAR);
2473
        emit(f,"\n");
2474
      }
2475
      if(c==PUSH){
2476
        if(CPU==6812)
2477
          emit(f,"\tpshd\n");
2478
        else
2479
          emit(f,"\tpshs\tb,a\n");
2480
        push(2);dontpop+=2;
2481
        if(regs[acc]) emit(f,"\tldd\t%ld,%s\n",loff-roff-2-stackoffset,regnames[sp]);
2482
      }else{
2483
        inc_addr(&p->z,-2,t);
2484
        store_reg(f,acc,&p->z,INT);
2485
      }
2486
      continue;
2487
    }
2488
 
2489
 
2490
    if(c==COMPARE){
2491
      int vadr;
2492
      if(drel&&(p->q1.flags&VARADR)&&!ISFUNC(p->q1.v->vtyp->flags)) vadr=1;
2493
      else if(drel&&(p->q2.flags&VARADR)&&!ISFUNC(p->q2.v->vtyp->flags)) vadr=2;
2494
      else if(pcrel&&(p->q1.flags&VARADR)&&ISFUNC(p->q1.v->vtyp->flags)) vadr=1;
2495
      else if(pcrel&&(p->q2.flags&VARADR)&&ISFUNC(p->q2.v->vtyp->flags)) vadr=2;
2496
      else vadr=0;
2497
      if(vadr!=1&&(vadr==2||isconst(q1)||ISRACC(q2))){
2498
        struct IC *p2;
2499
        o=p->q1;p->q1=p->q2;p->q2=o;
2500
        p2=p->next;
2501
        while(p2&&p2->code==FREEREG) p2=p2->next;
2502
        if(!p2||p2->code<BEQ||p2->code>BGT) ierror(0);
2503
        if(p2->code==BLT) p2->code=BGT;
2504
        else if(p2->code==BGT) p2->code=BLT;
2505
        else if(p2->code==BLE) p2->code=BGE;
2506
        else if(p2->code==BGE) p2->code=BLE;
2507
      }
2508
      /* case with two relative addresses */
2509
      if(drel&&(p->q2.flags&VARADR)&&!ISFUNC(p->q2.v->vtyp->flags)) skip_rel=1;
2510
      if(pcrel&&(p->q2.flags&VARADR)&&ISFUNC(p->q2.v->vtyp->flags)) skip_rel=1;
2511
    }
2512
#if 0
2513
    /* TODO: fix cc */
2514
    if(c==COMPARE&&isconst(q2)){
2515
      eval_const(&p->q2.val,t);
2516
      if(ISNULL()){
2517
        if(cc&&(cc_t&NU)==(t&NU)&&compare_objects(cc,&p->q1)){
2518
          lastcomp=t;continue;
2519
        }
2520
      }
2521
    }
2522
#endif
2523
 
2524
    if(!short_add)
2525
      switch_IC(p);
2526
 
2527
    if(c==CONVERT){
2528
      int to=p->typf2&NU;
2529
      if(to==INT) to=SHORT;
2530
      if(to==(UNSIGNED|INT)||to==NPOINTER) to=(UNSIGNED|SHORT);
2531
      if(to==FPOINTER||to==HPOINTER) to=(UNSIGNED|LONG);
2532
      if((t&NU)==INT) t=SHORT;
2533
      if((t&NU)==(UNSIGNED|INT)||(t&NU)==NPOINTER) t=(UNSIGNED|SHORT);
2534
      if((t&NQ)==FPOINTER||(t&NQ)==HPOINTER) t=(UNSIGNED|LONG);
2535
      /*if((t&NQ)>=LONG||(to&NQ)>=LONG) ierror(0);*/
2536
      if((to&NQ)<=LONG&&(t&NQ)<=LONG){
2537
        if((to&NQ)<(t&NQ)){
2538
          if(ISLWORD(t)){
2539
            get_acc(f,p);
2540
            load_reg(f,acc,&p->q1,to);
2541
            if((to&NU)==CHAR)
2542
              emit(f,SEX);
2543
            else if((to&NU)==(UNSIGNED|CHAR))
2544
              emit(f,"\tclra\n");
2545
            inc_addr(&p->z,2,t);
2546
            store_reg(f,acc,&p->z,INT);
2547
            inc_addr(&p->z,-2,t);
2548
            if(to&UNSIGNED){
2549
              emit(f,"\tclra\n\tclrb\n");
2550
            }else{
2551
              if(CPU==6812)
2552
                emit(f,"\texg\ta,b\n");
2553
              else
2554
                emit(f,"\ttfr\ta,b\n");
2555
              emit(f,SEX);
2556
              emit(f,"\ttfr\ta,b\n");
2557
            }
2558
            store_reg(f,acc,&p->z,INT);
2559
            continue;
2560
          }
2561
          /*emit(f,"#conv RACC=%d, regs=%d scratch=%d\n",(int)ISRACC(z),regs[acc],scratchreg(acc,p));*/
2562
          if(!ISRACC(z))
2563
            get_acc(f,p);
2564
          load_reg(f,acc,&p->q1,to);
2565
          if(to&UNSIGNED)
2566
            emit(f,"\tclra\n");
2567
          else
2568
            emit(f,SEX);
2569
          store_reg(f,acc,&p->z,t);
2570
          cc=&p->z;cc_t=t;
2571
          continue;
2572
        }else if((to&NQ)>(t&NQ)){
2573
          if(!ISRACC(z)&&!ISRACC(q1))
2574
            get_acc(f,p);
2575
          if(ISLWORD(to))
2576
            inc_addr(&p->q1,2,to);
2577
          load_reg(f,acc,&p->q1,to);
2578
          store_reg(f,acc,&p->z,t);
2579
          continue;
2580
        }else{
2581
          c=ASSIGN;
2582
          p->q2.val.vmax=sizetab[t&NQ];
2583
        }
2584
      }
2585
    }
2586
    if(c==KOMPLEMENT){
2587
      cc=0;
2588
      if(compare_objects(&p->q1,&p->z)&&!isreg(q1)&&(p->q1.flags&(REG|DREFOBJ))!=DREFOBJ&&(!p->q1.am||p->q1.am->flags!=ACC_IND)){
2589
        emit(f,"\tcom\t");
2590
        emit_obj(f,&p->z,t);
2591
        emit(f,"\n");
2592
        if(ISHWORD(t)){
2593
          mobj=p->z;
2594
          inc_addr(&mobj,1,t);
2595
          emit(f,"\tcom\t");
2596
          emit_obj(f,&mobj,INT);
2597
          emit(f,"\n");
2598
        }
2599
        continue;
2600
      }
2601
      if((!isreg(z)||p->z.reg!=acc)&&regs[acc]&&!scratchreg(acc,p))
2602
        get_acc(f,p);
2603
      load_reg(f,acc,&p->q1,t);
2604
      emit(f,"\tcoma\n\tcomb\n");
2605
      store_reg(f,acc,&p->z,t);
2606
      continue;
2607
    }
2608
    if(c==MINUS){
2609
      if((!isreg(z)||p->z.reg!=acc)&&regs[acc]&&!scratchreg(acc,p))
2610
        get_acc(f,p);
2611
      if(isreg(q1)){
2612
        load_reg(f,acc,&p->q1,t);
2613
        emit(f,"\tnega\n\tnegb\n\tsbca\t#0\n");
2614
      }else{
2615
        if(CPU!=6812&&!optsize)
2616
          emit(f,"\tldd\t#0\n");
2617
        else
2618
          emit(f,"\tclra\n\tclrb\n");
2619
        emit(f,"\tsubd\t");
2620
        emit_obj(f,&p->q1,t);
2621
        emit(f,"\n");
2622
      }
2623
      cc=&p->z;cc_t=t;
2624
      store_reg(f,acc,&p->z,t);
2625
      continue;
2626
    }
2627
    if(c==SETRETURN){
2628
      if(isreg(q1)&&p->q1.reg==p->z.reg) continue;
2629
      if(p->z.reg){
2630
        if(ISLWORD(t)){
2631
          inc_addr(&p->q1,0,t);
2632
          load_reg(f,ix,&p->q1,INT);
2633
          BSET(regs_modified,ix);
2634
          inc_addr(&p->q1,2,t);
2635
        }
2636
        load_reg(f,acc,&p->q1,t);
2637
        BSET(regs_modified,acc);
2638
 
2639
      }
2640
      continue;
2641
    }
2642
    if(c==GETRETURN){
2643
      if(isreg(z)&&p->z.reg==p->q1.reg) continue;
2644
      if(p->q1.reg){
2645
        if(ISLWORD(t)){
2646
          store_reg(f,ix,&p->z,INT);
2647
          BSET(regs_modified,ix);
2648
          inc_addr(&p->z,2,t);
2649
        }
2650
        store_reg(f,acc,&p->z,(t&NQ)==CHAR?t:INT);
2651
      }
2652
      continue;
2653
    }
2654
    if(c==CALL){
2655
      int reg,jmp=0;
2656
      cc=0;
2657
      if(!calc_regs(p,f!=0)&&v->fi) v->fi->flags&=~ALL_REGS;
2658
      if((p->q1.flags&(VAR|DREFOBJ))==VAR&&!strcmp("__va_start",p->q1.v->identifier)){
2659
        long of=va_offset(v)+loff+2;
2660
        emit(f,"\ttfr\t%s,d\n",regnames[sp]);
2661
        if(of) emit(f,"\taddd\t#%ld\n",of);
2662
        continue;
2663
      }
2664
      if((p->q1.flags&VAR)&&p->q1.v->fi&&p->q1.v->fi->inline_asm){
2665
        emit_inline_asm(f,p->q1.v->fi->inline_asm);
2666
        jmp=1;
2667
      }else{
2668
        if(stackoffset==0&&!have_frame&&!strcmp(ret,"rts")){
2669
          struct IC *p2;
2670
          jmp=1;
2671
          for(p2=p->next;p2;p2=p2->next){
2672
            if(p2->code!=FREEREG&&p2->code!=ALLOCREG&&p2->code!=LABEL){
2673
              jmp=0;break;
2674
            }
2675
          }
2676
        }
2677
        if(p->q1.flags&DREFOBJ){
2678
          /*FIXME: test this*/
2679
          if(jmp)
2680
            emit(f,"\tjmp\t");
2681
          else
2682
            emit(f,"\tjsr\t");
2683
          if (p->q1.v->tattr&FAR)
2684
                emit(f,"\tfar\t");
2685
          emit_obj(f,&p->q1,t);
2686
          emit(f,"\n");
2687
        }else{
2688
          if(jmp){
2689
            emit(f,"\t%s\t",jmpinst); /*emit(f,"\tbra\t");*/
2690
            /*if(!need_return) ret=0;*/ /*TODO: works with optimizer? */
2691
          }else{
2692
            emit(f,"\t%s\t",jsrinst); /*emit(f,"\tbsr\t");*/
2693
          }
2694
          if (p->q1.v->tattr&FAR)
2695
                emit(f,"\tfar\t");
2696
          if(pcrel){
2697
            pcrel=0;
2698
            emit_obj(f,&p->q1,t);
2699
            pcrel=1;
2700
          }else
2701
            emit_obj(f,&p->q1,t);
2702
          emit(f,"\n");
2703
        }
2704
      }
2705
      if(stack_valid){
2706
        int i;
2707
        if(p->call_cnt<=0){
2708
          err_ic=p;if(f) error(320);
2709
          stack_valid=0;
2710
        }
2711
        for(i=0;stack_valid&&i<p->call_cnt;i++){
2712
          if(p->call_list[i].v->fi&&(p->call_list[i].v->fi->flags&ALL_STACK)){
2713
            /*FIXME: size of return addr depends on mode */
2714
            if(!jmp) push(2);
2715
            callee_push(zm2l(p->call_list[i].v->fi->stack1));
2716
            if(!jmp) pop(2);
2717
          }else{
2718
            err_ic=p;if(f) error(317,p->call_list[i].v->identifier);
2719
            stack_valid=0;
2720
          }
2721
        }
2722
      }
2723
      if(!zmeqto(l2zm(0L),p->q2.val.vmax)){
2724
        notpopped+=zm2l(p->q2.val.vmax);
2725
        dontpop-=zm2l(p->q2.val.vmax);
2726
        if(!(g_flags[2]&USEDFLAG)&&stackoffset==-notpopped){
2727
          /*  Entfernen der Parameter verzoegern  */
2728
        }else{
2729
          gen_pop(f,zm2l(p->q2.val.vmax));
2730
          notpopped-=zm2l(p->q2.val.vmax);
2731
        }
2732
      }
2733
      continue;
2734
    }
2735
    if(c==ASSIGN||c==PUSH){
2736
      if(c==PUSH) dontpop+=zm2l(p->q2.val.vmax);
2737
      if(!zmleq(p->q2.val.vmax,l2zm(2L))){
2738
        unsigned long size;int qr=0,zr=0,cr=0,px=0,py=0,pu=0,pd=0,lq=0,lz=0;
2739
        size=zm2l(p->q2.val.vmax);
2740
        if(c==ASSIGN){
2741
          if(!p->z.am&&(p->z.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&ISIDX(p->z.reg)){
2742
            zr=p->z.reg;lz=1;
2743
          }
2744
        }
2745
        if(!p->q1.am&&(p->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&ISIDX(p->q1.reg)&&p->q1.reg!=zr){
2746
          qr=p->q1.reg;lq=1;
2747
        }
2748
        if(!qr){
2749
          if(zr==ix) qr=iy;
2750
          else if(zr==iy||zr==iu) qr=ix;
2751
          else{qr=ix;zr=iy;}
2752
        }else if(!zr){
2753
          if(qr==ix) zr=iy; else zr=ix;
2754
        }
2755
        if(CPU!=6812){
2756
          if(qr!=iu&&zr!=iu) cr=iu;
2757
          if(qr!=ix&&zr!=ix) cr=ix;
2758
          if(qr!=iy&&zr!=iy) cr=iy;
2759
          if(!cr) ierror(0);
2760
        }
2761
        if(c==PUSH){
2762
          emit(f,"\tleas\t%ld,%s\n",SGN16(-size),regnames[sp]);
2763
          push(size);
2764
        }
2765
        if(CPU!=6812&&(drel||!regused[iu]||(regs[iu]&&!scratchreg(iu,p)))){
2766
          if(c==PUSH)
2767
            emit(f,"\tstu\t%ld,%s\n",loff-roff-8-stackoffset,regnames[sp]);
2768
          else{
2769
            emit(f,SPUSH("u"));
2770
            push(2);
2771
          }
2772
          pu=1;
2773
        }
2774
        if(!regused[iy]||(regs[iy]&&!scratchreg(iy,p))){
2775
          if(c==PUSH)
2776
            emit(f,"\tsty\t%ld,%s\n",loff-roff-4-stackoffset,regnames[sp]);
2777
          else{
2778
            emit(f,SPUSH("y"));
2779
            push(2);
2780
          }
2781
          py=1;
2782
        }
2783
        if(regs[ix]&&!scratchreg(ix,p)){
2784
          if(c==PUSH)
2785
            emit(f,"\tstx\t%ld,%s\n",loff-roff-2-stackoffset,regnames[sp]);
2786
          else{
2787
            emit(f,SPUSH("x"));
2788
            push(2);
2789
          }
2790
          px=1;
2791
        }
2792
        if(!lq) load_addr(f,qr,&p->q1);
2793
        if(c==PUSH)
2794
          emit(f,"\ttfr\t%s,%s\n",regnames[sp],regnames[zr]);
2795
        else
2796
          if(!lz) load_addr(f,zr,&p->z);
2797
        if(size<=6||(size<=16&&!optsize)){
2798
          if(CPU!=6812){
2799
            if(!scratchreg(acc,p)){
2800
              if(c==PUSH)
2801
                emit(f,"\tstd\t%ld,%s\n",loff-roff-6-stackoffset,regnames[sp]);
2802
              else{
2803
                emit(f,SPUSHD);
2804
                push(2);
2805
              }
2806
              pd=2;
2807
            }
2808
          }
2809
          while(size>2){
2810
            if(CPU==6812)
2811
              emit(f,"\tmovw\t2,%s+,2,%s+\n",regnames[qr],regnames[zr]);
2812
            else
2813
              emit(f,"\tldd\t,%s++\n\tstd\t,%s++\n",regnames[qr],regnames[zr]);
2814
            size-=2;
2815
          }
2816
          if(CPU==6812)
2817
            emit(f,"\tmov%c\t0,%s,0,%s\n",size==2?'w':'b',regnames[qr],regnames[zr]);
2818
          else
2819
            emit(f,"\tld%c\t,%s\n\tst%c\t,%s\n",size==2?'d':'b',regnames[qr],size==2?'d':'b',regnames[zr]);
2820
        }else{
2821
          int l=++label,cnt=(int)(optsize?size:size/8);
2822
          if(regs[acc]&&!scratchreg(acc,p)){
2823
            if(c==PUSH)
2824
              emit(f,"\tst%c\t%ld,%s\n",(CPU!=6812&&cnt<=bytemask)?'b':'d',loff-roff-6-stackoffset,regnames[sp]);
2825
            else{
2826
              if(CPU!=6812&&cnt<=bytemask){
2827
                emit(f,SPUSH("b"));
2828
                push(1);
2829
              }else{
2830
                emit(f,SPUSHD);
2831
                push(2);
2832
              }
2833
            }
2834
            pd=(CPU!=6812&&cnt<=bytemask)?1:2;
2835
          }
2836
          if(CPU!=6812&&cnt<=bytemask)
2837
            emit(f,"\tldb\t#%lu\n",cnt);
2838
          else
2839
            emit(f,"\tldd\t#%lu\n",cnt);
2840
          cc=0;
2841
#if 0
2842
          if(CPU!=6812&&((!regsa[iu]&&regs[iu])||drel)){
2843
            if(c==PUSH){
2844
              emit(f,"\tstu\t%ld,%s\n",loff-roff-8-stackoffset,regnames[sp]);
2845
            }else{
2846
              emit(f,SPUSH("u"));push(2);
2847
            }
2848
          }
2849
#endif
2850
          emit(f,"%s%d:\n",labprefix,l);
2851
          if(CPU==6812){
2852
            if(optsize){
2853
              emit(f,"\tmovb\t2,%s+,2,%s+\n",regnames[qr],regnames[zr]);
2854
            }else{
2855
              emit(f,"\tmovw\t2,%s+,2,%s+\n",regnames[qr],regnames[zr]);
2856
              emit(f,"\tmovw\t2,%s+,2,%s+\n",regnames[qr],regnames[zr]);
2857
              emit(f,"\tmovw\t2,%s+,2,%s+\n",regnames[qr],regnames[zr]);
2858
              emit(f,"\tmovw\t2,%s+,2,%s+\n",regnames[qr],regnames[zr]);
2859
              size=size&7;
2860
            }
2861
            emit(f,"\tdbne\td,%s%d\n",labprefix,l);
2862
          }else{
2863
            if(optsize){
2864
              emit(f,"\tld%s\t,%s+\n\tst%s\t,%s+\n",regnames[cr],regnames[qr],regnames[cr],regnames[zr]);
2865
              size&=1;
2866
            }else{
2867
              emit(f,"\tld%s\t,%s++\n\tst%s\t,%s++\n",regnames[cr],regnames[qr],regnames[cr],regnames[zr]);
2868
              emit(f,"\tld%s\t,%s++\n\tst%s\t,%s++\n",regnames[cr],regnames[qr],regnames[cr],regnames[zr]);
2869
              emit(f,"\tld%s\t,%s++\n\tst%s\t,%s++\n",regnames[cr],regnames[qr],regnames[cr],regnames[zr]);
2870
              emit(f,"\tld%s\t,%s++\n\tst%s\t,%s++\n",regnames[cr],regnames[qr],regnames[cr],regnames[zr]);
2871
              size&=7;
2872
            }
2873
            if(cnt<=bytemask)
2874
              emit(f,"\tdecb\n");
2875
            else
2876
              emit(f,"\tsubd\t#1\n");
2877
            emit(f,"\tbne\t%s%d\n",labprefix,l);
2878
          }
2879
#if 0
2880
          if(CPU!=6812&&((!regsa[iu]&&regs[iu])||drel)){
2881
            if(c==PUSH){
2882
              emit(f,"\tldu\t%ld,%s\n",loff-roff-8-stackoffset,regnames[sp]);
2883
            }else{
2884
              emit(f,SPULL("u"));pop(2);
2885
            }
2886
          }
2887
#endif
2888
          while(size>=2){
2889
            if(CPU==6812)
2890
              emit(f,"\tmovw\t2,%s+,2,%s+\n",regnames[qr],regnames[zr]);
2891
            else
2892
              emit(f,"\tldd\t,%s++\n\tstd\t,%s++\n",regnames[qr],regnames[zr]);
2893
            size-=2;
2894
          }
2895
          if(size){
2896
            if(CPU==6812)
2897
              emit(f,"\tmovb\t0,%s,0,%s\n",regnames[qr],regnames[zr]);
2898
            else
2899
              emit(f,"\tldb\t,%s\n\tstb\t,%s\n",regnames[qr],regnames[zr]);
2900
          }
2901
        }
2902
        if(pd){
2903
          if(c==PUSH)
2904
            emit(f,"\tld%c\t%ld,%s\n",(pd==1)?'b':'d',loff-roff-6-stackoffset,regnames[sp]);
2905
          else{
2906
            if(pd==1){
2907
              emit(f,SPULL("b"));
2908
              pop(1);
2909
            }else{
2910
              emit(f,SPULLD);
2911
              pop(2);
2912
            }
2913
          }
2914
        }
2915
        if(px){
2916
          if(c==PUSH)
2917
            emit(f,"\tldx\t%ld,%s\n",loff-roff-2-stackoffset,regnames[sp]);
2918
          else{
2919
            emit(f,SPULL("x"));
2920
            pop(2);
2921
          }
2922
        }
2923
        if(py){
2924
          if(c==PUSH)
2925
            emit(f,"\tldy\t%ld,%s\n",loff-roff-4-stackoffset,regnames[sp]);
2926
          else{
2927
            emit(f,SPULL("y"));
2928
            pop(2);
2929
          }
2930
        }
2931
        if(pu){
2932
          if(c==PUSH)
2933
            emit(f,"\tldu\t%ld,%s\n",loff-roff-8-stackoffset,regnames[sp]);
2934
          else{
2935
            emit(f,SPULL("u"));
2936
            pop(2);
2937
          }
2938
        }
2939
        continue;
2940
      }
2941
      if(!ISSCALAR(t)) t=zmeqto(p->q2.val.vmax,l2zm(1L))?CHAR:INT;
2942
      if((t&NQ)==CHAR&&!zmeqto(p->q2.val.vmax,l2zm(1L))) t=INT;
2943
      if(mov_op(&p->q1)&&(c==PUSH||mov_op(&p->z))){
2944
        emit(f,"\tmov%c\t",ISHWORD(t)?'w':'b');
2945
        emit_obj(f,&p->q1,t);
2946
        if(c==ASSIGN){
2947
          emit(f,",");
2948
          emit_obj(f,&p->z,t);
2949
          emit(f,"\n");
2950
        }else{
2951
          emit(f,",%d,-%s\n",ISHWORD(t)?2:1,regnames[sp]);
2952
          push(ISHWORD(t)?2:1);
2953
        }
2954
        continue;
2955
      }
2956
      if(((regs[acc]&&regs[ix])||(t&NQ)==CHAR)&&(p->q1.flags&KONST)&&!isreg(z)){
2957
        eval_const(&p->q1.val,t);
2958
        if(zmeqto(vmax,l2zm(0L))&&zumeqto(vumax,ul2zum(0UL))&&((p->z.flags&(REG|DREFOBJ))!=DREFOBJ||(t&NQ)==CHAR)&&(!p->z.am||p->z.am->flags!=ACC_IND||(t&NQ)==CHAR)){
2959
          emit(f,"\tclr\t");
2960
          if(c==ASSIGN){
2961
            emit_obj(f,&p->z,t);emit(f,"\n");
2962
          }else{
2963
            emit(f,CPU==6812?"1,-sp\n":",-s\n");
2964
            push(1);
2965
          }
2966
          if(!ISHWORD(t)) continue;
2967
          emit(f,"\tclr\t");
2968
          if(c==ASSIGN){
2969
            mobj=p->z;
2970
            inc_addr(&mobj,1,t);
2971
            emit_obj(f,&mobj,t);emit(f,"\n");
2972
          }else{
2973
            emit(f,CPU==6812?"1,-sp\n":",-s\n");
2974
            push(1);
2975
          }
2976
          continue;
2977
        }
2978
 
2979
      }
2980
      if(c==PUSH){
2981
        int st=0;
2982
        if(isreg(q1)){
2983
          reg=p->q1.reg;
2984
        }else{
2985
          if((t&NQ)==CHAR||!regs[acc]||scratchreg(acc,p)) reg=acc;
2986
          else if(!regs[ix]||scratchreg(ix,p)) reg=ix;
2987
          else if(regused[iy]&&(!regs[iy]||scratchreg(iy,p))) reg=iy;
2988
          else if(regused[iu]&&!drel&&CPU!=6812&&(!regs[iu]||scratchreg(iu,p))) reg=iu;
2989
          else reg=acc;
2990
          if(regs[reg]&&!scratchreg(reg,p)){
2991
            st=1;
2992
            emit(f,"\tst%s\t%ld,%s\n",regnames[reg],(long)loff-roff-2-stackoffset,regnames[sp]);
2993
          }
2994
          load_reg(f,reg,&p->q1,t);
2995
        }
2996
        if((t&NQ)==CHAR)
2997
          emit(f,SPUSH("b"));
2998
        else if(reg==ix)
2999
          emit(f,SPUSH("x"));
3000
        else if(reg==iy)
3001
          emit(f,SPUSH("y"));
3002
        else if(reg==iu)
3003
          emit(f,SPUSH("u"));
3004
        else
3005
          emit(f,SPUSHD);
3006
        push(zm2l(p->q2.val.vmax));
3007
        if(st)
3008
          emit(f,"\tld%s\t%ld,%s\n",regnames[reg],(long)loff-roff-2-stackoffset,regnames[sp]);
3009
        continue;
3010
      }
3011
      if(c==ASSIGN){
3012
        if(isreg(q1)&&isreg(z)){
3013
          if(p->q1.reg!=p->z.reg)
3014
            emit(f,"\ttfr\t%s,%s\n",regnames[p->q1.reg],regnames[p->z.reg]);
3015
        }else if(isreg(q1)){
3016
          store_reg(f,p->q1.reg,&p->z,t);
3017
        }else if(isreg(z)){
3018
          load_reg(f,p->z.reg,&p->q1,t);
3019
        }else{
3020
          reg=get_reg(f,p,t);
3021
          load_reg(f,reg,&p->q1,t);
3022
          store_reg(f,reg,&p->z,t);
3023
        }
3024
        continue;
3025
      }
3026
      ierror(0);
3027
    }
3028
    if(c==ADDRESS){
3029
      int px=0;
3030
      if(isreg(z)){
3031
        reg=p->z.reg;
3032
      }else if(!regs[ix]){
3033
        reg=ix;
3034
      }else if(!regs[iy]){
3035
        reg=iy;
3036
      }else{
3037
        /*FIXME: test if x used in q1 */
3038
        px=1;
3039
        emit(f,SPUSH("x"));
3040
        reg=ix;
3041
        push(2);
3042
      }
3043
      load_addr(f,reg,&p->q1);
3044
      if(!(p->z.flags&REG)||p->z.reg!=reg)
3045
        store_reg(f,reg,&p->z,p->typf2);
3046
      if(px){
3047
        emit(f,SPULL("x"));
3048
        pop(2);
3049
      }
3050
      continue;
3051
    }
3052
 
3053
    if((c==MULT||c==DIV||(c==MOD&&(p->typf&UNSIGNED)))&&isconst(q2)){
3054
      long ln;
3055
      eval_const(&p->q2.val,t);
3056
      if(zmleq(l2zm(0L),vmax)&&zumleq(ul2zum(0UL),vumax)){
3057
        if((ln=pof2(vumax))&&ln<5){
3058
          if(c==MOD){
3059
            vmax=zmsub(vmax,l2zm(1L));
3060
            c=p->code=c=AND;
3061
          }else{
3062
            vmax=l2zm(ln-1);
3063
            if(c==DIV) p->code=c=RSHIFT; else p->code=c=LSHIFT;
3064
          }
3065
          c=p->code;
3066
          gval.vmax=vmax;
3067
          eval_const(&gval,MAXINT);
3068
          if(c==AND){
3069
            insert_const(&p->q2.val,t);
3070
          }else{
3071
            insert_const(&p->q2.val,t);
3072
            p->typf2=INT;
3073
          }
3074
        }
3075
      }
3076
    }
3077
    if(c==MOD||c==DIV){
3078
      ierror(0);
3079
      continue;
3080
    }
3081
 
3082
 
3083
    if((c==ADD||c==SUB)&&(p->q2.flags&(KONST|DREFOBJ))==KONST&&(p->q1.flags&(REG|DREFOBJ))!=REG&&(p->q1.flags&(REG|DREFOBJ))!=DREFOBJ&&!p->q1.am&&!p->z.am&&compare_objects(&p->q1,&p->z)){
3084
      eval_const(&p->q2.val,t);
3085
      if(c==SUB) vmax=zmsub(Z0,vmax);
3086
      if((t&NQ)==CHAR&&zmeqto(vmax,Z1)){
3087
        emit(f,"\tinc\t");
3088
        emit_obj(f,&p->z,t);
3089
        emit(f,"\n");
3090
        continue;
3091
      }else if((t&NQ)==CHAR&&zmeqto(vmax,l2zm(-1L))){
3092
        emit(f,"\tdec\t");
3093
        emit_obj(f,&p->z,t);
3094
        emit(f,"\n");
3095
        continue;
3096
      }else if(((t&NQ)==SHORT||(t&NQ)==INT)&&zmeqto(vmax,l2zm(1L))){
3097
        inc_addr(&p->z,1,t);
3098
        emit(f,"\tinc\t");
3099
        emit_obj(f,&p->z,t);
3100
        emit(f,"\n");
3101
        emit(f,"\tbne\t%s%d\n",labprefix,++label);
3102
        inc_addr(&p->z,-1,t);
3103
        emit(f,"\tinc\t");
3104
        emit_obj(f,&p->z,t);
3105
        emit(f,"\n");
3106
        emit(f,"%s%d:\n",labprefix,label);
3107
        continue;
3108
      }else if(regs[acc]&&((t&NQ)==SHORT||(t&NQ)==INT)&&zmeqto(vmax,l2zm(-1L))){
3109
        inc_addr(&p->z,1,t);
3110
        emit(f,"\ttst\t");
3111
        emit_obj(f,&p->z,t);
3112
        emit(f,"\n");
3113
        emit(f,"\tbne\t%s%d\n",labprefix,++label);
3114
        inc_addr(&p->z,-1,t);
3115
        emit(f,"\tdec\t");
3116
        emit_obj(f,&p->z,t);
3117
        emit(f,"\n");
3118
        emit(f,"%s%d:\n",labprefix,label);
3119
        inc_addr(&p->z,1,t);
3120
        emit(f,"\tdec\t");
3121
        emit_obj(f,&p->z,t);
3122
        emit(f,"\n");
3123
        continue;
3124
      }
3125
    }
3126
 
3127
    if((c>=LSHIFT&&c<=MOD)||c==ADDI2P||c==SUBIFP||c==SUBPFP||(c>=OR&&c<=AND)||c==COMPARE){
3128
      char *s;
3129
      /*FIXME: nicht immer besser*/
3130
      if(ISLWORD(t)&&c==LSHIFT&&isconst(q2)){
3131
        eval_const(&p->q2.val,t);
3132
        if(zm2l(vmax)==1){
3133
          p->code=c=ADD;
3134
          p->q2=p->q1;
3135
        }
3136
      }
3137
      if((c==ADD||c==ADDI2P||c==MULT||(c>=OR&&c<=AND))&&isreg(q2)&&!isreg(q1)&&!short_add){
3138
        o=p->q1;p->q1=p->q2;p->q2=o;
3139
      }
3140
      if((c==ADD||c==MULT||(c>=OR&&c<=AND))&&isreg(q2)&&p->q2.reg==acc&&!short_add){
3141
        o=p->q1;p->q1=p->q2;p->q2=o;
3142
      }
3143
      if(c==MULT||c==MOD){
3144
        if((!isreg(z)||p->z.reg!=acc)&&regs[acc]&&!scratchreg(acc,p))
3145
          get_acc(f,p);
3146
        reg=acc;
3147
        /*FIXME: y bzw. x-Register*/
3148
      }else if(c==LSHIFT||c==RSHIFT||c==AND||c==OR||c==XOR){
3149
        if((!isreg(z)||p->z.reg!=acc)&&regs[acc]&&!scratchreg(acc,p))
3150
          get_acc(f,p);
3151
        reg=acc;
3152
      }else if(c==DIV){
3153
        reg=ix;
3154
        ierror(0);
3155
      }else if(isreg(z)){
3156
        reg=p->z.reg;
3157
      }else if(isreg(q1)&&(c==COMPARE||scratchreg(p->q1.reg,p))){
3158
        reg=p->q1.reg;
3159
      }else{
3160
        if(c==ADD||c==SUB||c==ADDI2P||c==SUBIFP||c==COMPARE){
3161
          if(ISRACC(q2))
3162
            reg=acc;
3163
          else
3164
            reg=get_reg(f,p,t);
3165
        }else{
3166
          get_acc(f,p);
3167
          reg=acc;
3168
        }
3169
      }
3170
      if(c==ADD||c==ADDI2P||c==SUB||c==SUBIFP){
3171
        int opdone=0;
3172
        if(isreg(q1)){
3173
          if(ISIDX(reg)&&ISIDX(p->q1.reg)&&isconst(q2)){
3174
            eval_const(&p->q2.val,short_add?short_add:q2typ(p));
3175
            if(CPU==6812&&p->q1.reg==reg&&zmeqto(vmax,l2zm(1L))&&zumeqto(vumax,ul2zum(1UL))){
3176
              emit(f,"\t%s%s\n",c==SUB?"de":"in",regnames[reg]);
3177
              /*FIXME: condition-codes for bne/beq could be used */
3178
            }else{
3179
              emit(f,"\tlea%s\t%ld,%s\n",regnames[reg],c==SUB?SGN16(-zm2l(vmax)):SGN16(zm2l(vmax)),regnames[p->q1.reg]);
3180
            }
3181
            opdone=1;
3182
          }else if((c==ADD||c==ADDI2P)&&ISIDX(reg)&&ISIDX(p->q1.reg)&&ISRACC(q2)){
3183
            emit(f,"\tlea%s\t%s,%s\n",regnames[reg],((t&NQ)==CHAR||(short_add&NQ)==CHAR)?"b":"d",regnames[p->q1.reg]);
3184
            opdone=1;
3185
          }else if((c==ADD||c==ADDI2P)&&ISIDX(reg)&&ISACC(p->q1.reg)&&ISRIDX(q2)){
3186
            emit(f,"\tlea%s\t%s,%s\n",regnames[reg],(t&NQ)==CHAR?"b":"d",regnames[p->q2.reg]);
3187
            opdone=1;
3188
          }else if((c==ADD||c==ADDI2P)&&p->q1.reg==acc&&ISIDX(reg)&&!short_add){
3189
            load_reg(f,reg,&p->q2,t);
3190
            emit(f,"\tlea%s\t%s,%s\n",regnames[reg],(t&NQ)==CHAR?"b":"d",regnames[reg]);
3191
            opdone=1;
3192
          }else if((c==ADD||c==ADDI2P)&&p->q1.reg==acc&&ISIDX(reg)&&(short_add&NU)==(UNSIGNED|CHAR)&&scratchreg(acc,p)){
3193
            emit(f,"\taddb\t");
3194
            emit_obj(f,&p->q2,short_add);
3195
            emit(f,"\n");
3196
            emit(f,"\tadca\t#0\n");
3197
            emit(f,"\ttfr\td,y\n");
3198
            opdone=1;
3199
          }else if((c==ADD||c==ADDI2P)&&ISACC(p->q1.reg)&&ISRACC(z)&&isreg(q2)&&ISIDX(p->q2.reg)){
3200
            if(!scratchreg(p->q2.reg,p)) emit(f,"\texg\t%s,%s\n",regnames[acc],regnames[p->q2.reg]);
3201
            emit(f,"\tlea%s\t%s,%s\n",regnames[p->q2.reg],regnames[acc],regnames[p->q2.reg]);
3202
            emit(f,"\texg\t%s,%s\n",regnames[acc],regnames[p->q2.reg]);
3203
            opdone=1;
3204
          }else if(p->q1.reg!=reg){
3205
            if(c==ADD||c==ADDI2P||!ISRACC(q2))
3206
              emit(f,"\ttfr\t%s,%s\n",regnames[p->q1.reg],regnames[reg]);
3207
          }
3208
        }else if(short_add&&c==SUB&&reg==acc&&!(short_add&UNSIGNED)){
3209
          load_reg(f,reg,&p->q2,short_add);
3210
          emit(f,"\tclra\n");
3211
          emit(f,"\tnegb\n");
3212
          emit(f,"\tsbca\t#0\n");
3213
          emit(f,"\taddd\t");
3214
          emit_obj(f,&p->q1,t);
3215
          emit(f,"\n");
3216
          store_reg(f,reg,&p->z,ztyp(p));
3217
          continue;
3218
        }else if(short_add&&c==ADD&&reg==acc){
3219
          load_reg(f,reg,&p->q2,short_add);
3220
          if(short_add&UNSIGNED)
3221
            emit(f,"\tclra\n");
3222
          else
3223
            emit(f,SEX);
3224
          emit(f,"\taddd\t");
3225
          emit_obj(f,&p->q1,t);
3226
          emit(f,"\n");
3227
          store_reg(f,reg,&p->z,ztyp(p));
3228
          continue;
3229
        }else{
3230
          if(!ISRACC(q2))
3231
            load_reg(f,reg,&p->q1,q1typ(p));
3232
        }
3233
        if(!opdone){
3234
          if(reg==acc){
3235
            if(ISRACC(q2)){
3236
              if(!ISRACC(z)) get_acc(f,p);
3237
              if(c==ADD||c==ADDI2P){
3238
                if(short_add){
3239
                  if(short_add&UNSIGNED)
3240
                    emit(f,"\tclra\n");
3241
                  else
3242
                    emit(f,SEX);
3243
                  emit(f,"\taddd\t");
3244
                  emit_obj(f,&p->q1,t);
3245
                  emit(f,"\n");
3246
                }else{
3247
                  if(CPU==6812)
3248
                    emit(f,"\tasld\n"); /* only cases with q1=q2=acc should remain */
3249
                  else{
3250
                    emit(f,"\taslb\n");
3251
                    if((t&NQ)!=CHAR)
3252
                      emit(f,"\trola\n");
3253
                  }
3254
                }
3255
              }else{
3256
                if(short_add){
3257
                  if(short_add&UNSIGNED)
3258
                    emit(f,"\tld%sa\t#255\n",(CPU==6812)?"a":"");
3259
                  else{
3260
                    emit(f,SEX);
3261
                    emit(f,"\tnega\n");
3262
                  }
3263
                  emit(f,"\tnegb\n\tsbca\t#0\n");
3264
                }else if((t&NQ)!=CHAR){
3265
                  emit(f,"\tnega\n\tnegb\n\tsbca\t#0\n");
3266
                }else{
3267
                  emit(f,"\tnegb\n");
3268
                }
3269
 
3270
                if(ISRIDX(q1)){
3271
                  emit(f,"\t%s%s\n",CPU==6812?"psh":"pshs\t",regnames[p->q1.reg]);
3272
                  emit(f,"\taddd\t%s\n",CPU==6812?"1,s+":",s++");
3273
                }else{
3274
                  emit(f,"\taddd\t");
3275
                  emit_obj(f,&p->q1,t);
3276
                  emit(f,"\n");
3277
                }
3278
              }
3279
            }else{
3280
              if(ISRIDX(q2)){
3281
                if(CPU==6812)
3282
                  emit(f,"\tpsh%s\n",regnames[p->q2.reg]);
3283
                else
3284
                  emit(f,"\tpshs\t%s\n",regnames[p->q2.reg]);
3285
                push(2);pop(2);
3286
                if(CPU==6812)
3287
                  emit(f,"\t%sd\t2,%s+\n",(c==ADD||c==ADDI2P)?"add":"sub",regnames[sp]);
3288
                else
3289
                  emit(f,"\t%sd\t,%s++\n",(c==ADD||c==ADDI2P)?"add":"sub",regnames[sp]);
3290
              }else{
3291
                emit(f,"\t%s%s\t",(c==ADD||c==ADDI2P)?"add":"sub",(short_add||(t&NQ)==CHAR)?"b":"d");
3292
                emit_obj(f,&p->q2,short_add?short_add:t);emit(f,"\n");
3293
                if(short_add){
3294
                  if(short_add&UNSIGNED)
3295
                    emit(f,"\t%s\t#0\n",c==ADD?"adca":"sbca");
3296
                  else
3297
                    ierror(0);
3298
                }
3299
                if(drel&&(p->q2.flags&VARADR)){
3300
                  if(CPU==6812) ierror(0);
3301
                  emit(f,"\tpshs\t%s\n",regnames[iu]);push(2);
3302
                  emit(f,"\t%sd\t,%s++\n",(c==ADD||c==ADDI2P)?"add":"sub",regnames[sp]);
3303
                  pop(2);
3304
                }
3305
              }
3306
            }
3307
            cc=&p->z;cc_t=t;
3308
          }else{
3309
            if(isconst(q2)){
3310
              long l;
3311
              eval_const(&p->q2.val,short_add?short_add:t);
3312
              l=zm2l(vmax);
3313
              if(c==SUB) l=-l;
3314
              /*FIXME: condition-codes for bne/beq could be used */
3315
              if(l==1&&reg==ix&&CPU==6812){
3316
                emit(f,"\tinx\n");
3317
              }else if(l==1&&reg==iy&&CPU==6812){
3318
                emit(f,"\tiny\n");
3319
              }else if(l==-1&&reg==ix&&CPU==6812){
3320
                emit(f,"\tdex\n");
3321
              }else if(l==-1&&reg==iy&&CPU==6812){
3322
                emit(f,"\tdey\n");
3323
              }else{
3324
                emit(f,"\tlea%s\t%ld,%s\n",regnames[reg],SGN16(l),regnames[reg]);
3325
              }
3326
            }else{
3327
              if(c!=ADD&&c!=ADDI2P){
3328
                if(!ISRACC(q2)){
3329
                  if(!scratchreg(acc,p))
3330
                    get_acc(f,p);
3331
                  load_reg(f,acc,&p->q2,t);
3332
                  if((t&NQ)!=CHAR){
3333
                    emit(f,"\tnega\n\tnegb\n\tsbca\t#0\n");
3334
                  }else{
3335
                    emit(f,"\tnegb\n");
3336
                  }
3337
                  /*load_reg(f,reg,&p->q1,t);*/
3338
                }else{
3339
                  get_acc(f,p);
3340
                  load_reg(f,reg,&p->q1,t);
3341
                  if((t&NQ)==CHAR)
3342
                    emit(f,"\tnegb\n");
3343
                  else
3344
                    emit(f,"\tnega\n\tnegb\n\tsbca\t#0\n");
3345
                }
3346
              }else if(!ISRACC(q2)){
3347
                get_acc(f,p);
3348
                if(short_add){
3349
                  load_reg(f,acc,&p->q2,short_add);
3350
                  if(short_add&UNSIGNED){
3351
                    if(reg==ix){
3352
                      emit(f,"\tabx\n");
3353
                      store_reg(f,reg,&p->z,ztyp(p));
3354
                      continue;
3355
                    }else{
3356
                      emit(f,"\tclra\n");
3357
                    }
3358
                  }else
3359
                    t=CHAR;
3360
                }else
3361
                  load_reg(f,acc,&p->q2,t);
3362
              }else{
3363
                load_reg(f,reg,&p->q1,t);
3364
                if(short_add&UNSIGNED)
3365
                  emit(f,"\tclra\n");
3366
                emit(f,"\tlea%s\t%s,%s\n",regnames[reg],((t&NU)==CHAR||(short_add&NU)==CHAR)?"b":"d",regnames[reg]);
3367
                store_reg(f,reg,&p->z,ztyp(p));
3368
                continue;
3369
              }
3370
              emit(f,"\tlea%s\t%s,%s\n",regnames[reg],(t&NQ)==CHAR?"b":"d",regnames[reg]);
3371
            }
3372
          }
3373
        }
3374
        store_reg(f,reg,&p->z,ztyp(p));
3375
        continue;
3376
      }
3377
      if(c!=LSHIFT&&c!=RSHIFT)
3378
        load_reg(f,reg,&p->q1,t);
3379
      if(c==MULT){
3380
        if(CPU==6812){
3381
          int py=0;
3382
          if(reg!=acc) ierror(reg);
3383
          if(!ISRY(q2)&&regs[iy]){
3384
            emit(f,"\tpshy\n");
3385
            push(2);
3386
            py=1;
3387
          }
3388
          load_reg(f,iy,&p->q2,t);
3389
          emit(f,"\temul\n");
3390
          if(py){
3391
            emit(f,SPULL("y"));
3392
            pop(2);
3393
          }
3394
          store_reg(f,acc,&p->z,t);
3395
          continue;
3396
        }else
3397
          ierror(0);
3398
      }
3399
      if(c==LSHIFT||c==RSHIFT){
3400
        if(isconst(q2)){
3401
          int l,oldl;
3402
          load_reg(f,acc,&p->q1,t);
3403
          eval_const(&p->q2.val,t);
3404
          oldl=l=zm2l(vmax);
3405
          if(l>=24){
3406
            if(CPU!=6812&&!optsize)
3407
              emit(f,"\tldd\t#0\n");
3408
            else
3409
              emit(f,"\tclra\n\tclrb\n");
3410
            l=0;
3411
          }
3412
          if(l>=8){
3413
            if(c==LSHIFT)
3414
              emit(f,"\t%s\n\tclrb\n",(CPU==6812)?"tba":"tfr\tb,a");
3415
            else{
3416
              if(t&UNSIGNED)
3417
                emit(f,"\ttfr\ta,b\n\tclra\n");
3418
              else{
3419
                emit(f,"\ttfr\ta,b\n");
3420
                emit(f,SEX);
3421
              }
3422
            }
3423
            l-=8;
3424
          }
3425
          while(l--){
3426
            if(c==RSHIFT){
3427
              if(t&UNSIGNED){
3428
                if((t&NQ)==CHAR)
3429
                  emit(f,"\tlsrb\n");
3430
                else
3431
                  emit(f,CPU==6809?"\tlsra\n\trorb\n":"\tlsrd\n");
3432
              }else{
3433
                if(oldl>12||(t&NQ)==CHAR)
3434
                  emit(f,"\tasrb\n");
3435
                else
3436
                  emit(f,"\tasra\n\trorb\n");
3437
              }
3438
            }else{
3439
              if((t&NQ)==CHAR)
3440
                emit(f,"\taslb\n");
3441
              else
3442
                emit(f,CPU==6809?"\taslb\n\trola\n":"\tasld\n");
3443
            }
3444
          }
3445
        }else{
3446
          int px;char *s;
3447
          if(regs[ix]&&!scratchreg(ix,p)&&(!isreg(z)||p->z.reg!=ix)){
3448
            emit(f,SPUSH("x"));
3449
            push(2);px=1;
3450
          }else
3451
            px=0;
3452
          if((p->typf2&NQ)==CHAR){
3453
            load_reg(f,acc,&p->q2,p->typf2);
3454
            emit(f,(p->typf2&UNSIGNED)?"\tclra\n":SEX);
3455
            emit(f,"\ttfr\td,x\n");
3456
          }else
3457
            load_reg(f,ix,&p->q2,t);
3458
          load_reg(f,acc,&p->q1,p->typf);
3459
          if((t&NQ)==CHAR)
3460
            emit(f,(p->typf2&UNSIGNED)?"\tclra\n":SEX);
3461
          if(c==LSHIFT) s="lsl";
3462
          else if(t&UNSIGNED) s="lsr";
3463
          else s="asr";
3464
          emit(f,"\t.global\t%s__%s\n",idprefix,s);
3465
          emit(f,"\t%s\t%s__%s\n",jsrinst,idprefix,s);
3466
          if(px){
3467
            emit(f,SPULL("x"));
3468
            /*emit(f,"\tpul%s\n",regnames[ix]);*/
3469
            pop(2);
3470
          }
3471
        }
3472
        cc=0;
3473
        store_reg(f,acc,&p->z,t);
3474
        continue;
3475
      }
3476
      if(c>=OR&&c<=AND){
3477
        s=logicals[c-OR];
3478
        if(p->q2.am&&p->q2.am->flags==ACC_IND){
3479
          mobj=p->q1;p->q1=p->q2;p->q2=mobj;
3480
        }
3481
        if(p->q2.flags&KONST){
3482
          unsigned long l,h;
3483
          eval_const(&p->q2.val,t);
3484
          l=zum2ul(vumax);
3485
          if((t&NQ)!=CHAR){
3486
            h=(l>>bitsperbyte)&bytemask;
3487
            if(c==AND&&h==0)
3488
              emit(f,"\tclra\n");
3489
            else if(c==XOR&&h==bytemask)
3490
              emit(f,"\tcoma\n");
3491
            else if((c==AND&&h!=bytemask)||(c==OR&&h!=0)||(c==XOR&&h!=0))
3492
              emit(f,"\t%sa\t#%lu\n",s,h);
3493
          }
3494
          h=l&bytemask;
3495
          if(c==AND&&h==0)
3496
            emit(f,"\tclrb\n");
3497
          else if(c==XOR&&h==bytemask)
3498
            emit(f,"\tcomb\n");
3499
          else if((c==AND&&h!=bytemask)||(c==OR&&h!=0)||(c==XOR&&h!=0))
3500
            emit(f,"\t%sb\t#%lu\n",s,h);
3501
        }else{
3502
          if(isreg(q2)){
3503
            if(p->q2.reg==acc){
3504
              if(c==XOR){
3505
                emit(f,"\tclrb\n");
3506
                if((t&NQ)!=CHAR) emit(f,"\tclra\n");
3507
              }
3508
            }else{
3509
              if((t&NQ)==CHAR){
3510
                emit(f,SPUSH("a"));
3511
                push(1);
3512
                emit(f,"\t%sa\t%s,%s+\n",s,CPU==6812?"1":"",regnames[sp]);
3513
                pop(1);
3514
              }else{
3515
                emit(f,"\t%s%s\n",(CPU==6812)?"psh":"pshs\t",regnames[p->q2.reg]);
3516
                push(2);
3517
                emit(f,"\t%sa\t%s,%s+\n",s,CPU==6812?"1":"",regnames[sp]);
3518
                emit(f,"\t%sb\t%s,%s+\n",s,CPU==6812?"1":"",regnames[sp]);
3519
                pop(2);
3520
              }
3521
            }
3522
          }else if((p->q2.flags&(REG|DREFOBJ))==DREFOBJ&&(t&NQ)!=CHAR){
3523
            int xr=0;
3524
            if(!regs[ix]) xr=ix;
3525
            else if(!regs[iy]) xr=iy;
3526
            else{
3527
              xr=ix;
3528
              emit(f,"\t%s%s\n",(CPU==6812)?"psh":"pshs\t",regnames[xr]);
3529
              push(2);
3530
 
3531
            }
3532
            BSET(regs_modified,xr);
3533
            load_addr(f,xr,&p->q2);
3534
            if((t&NQ)==CHAR)
3535
              emit(f,"\t%sb\t0,%s\n",s,regnames[xr]);
3536
            else{
3537
              emit(f,"\t%sa\t0,%s\n",s,regnames[xr]);
3538
              emit(f,"\t%sb\t1,%s\n",s,regnames[xr]);
3539
            }
3540
            if(regs[ix]&&xr==ix){
3541
              emit(f,SPULL("x"));
3542
              pop(2);
3543
            }
3544
          }else{
3545
            emit(f,"\t%sb\t",s);
3546
            if((t&NQ)!=CHAR) inc_addr(&p->q2,1,t);
3547
            emit_obj(f,&p->q2,t);
3548
            emit(f,"\n");
3549
            if((t&NQ)!=CHAR){
3550
              inc_addr(&p->q2,-1,t);
3551
              emit(f,"\t%sa\t",s);
3552
              emit_obj(f,&p->q2,t);
3553
              emit(f,"\n");
3554
            }
3555
          }
3556
        }
3557
        cc=0;
3558
        store_reg(f,reg,&p->z,t);
3559
        continue;
3560
      }else if(c==COMPARE){
3561
        lastcomp=t;
3562
        if(isreg(q2)){
3563
          emit(f,"\t%s%s\n",(CPU==6812)?"psh":"pshs\t",regnames[p->q2.reg]);
3564
          push(2);
3565
        }
3566
        if(reg==acc){
3567
          if((t&NQ)==CHAR)
3568
            emit(f,"\tcmpb\t");
3569
          else
3570
            emit(f,SCMP("d"));
3571
        }else if(reg==ix){
3572
          emit(f,SCMP("x"));
3573
        }else if(reg==iy){
3574
          emit(f,SCMP("y"));
3575
        }else if(reg==iu){
3576
          emit(f,SCMP("u"));
3577
        }else
3578
          ierror(0);
3579
        if(isreg(q2)){
3580
          if(CPU==6812)
3581
            emit(f,"2,%s+\n",regnames[sp]);
3582
          else
3583
            emit(f,",%s++\n",regnames[sp]);
3584
          pop(2);
3585
        }else{
3586
          emit_obj(f,&p->q2,t);emit(f,"\n");
3587
        }
3588
        continue;
3589
      }
3590
      ierror(0);
3591
    }
3592
    pric2(stdout,p);
3593
    ierror(0);
3594
  }
3595
  if(notpopped){
3596
    gen_pop(f,notpopped);
3597
    notpopped=0;
3598
  }
3599
  function_bottom(f,v,loff);
3600
  if(debug_info){
3601
    emit(f,"%s%d:\n",labprefix,++label);
3602
    dwarf2_function(f,v,label);
3603
    if(f) section=-1;
3604
  }
3605
}
3606
 
3607
int shortcut(int c,int t)
3608
{
3609
  if(c==COMPARE||c==ADD||c==SUB||c==AND||c==OR||c==XOR) return 1;
3610
  if((c==LSHIFT||c==RSHIFT)&&ISCHWORD(t&NQ)) return 1;
3611
  return 0;
3612
}
3613
 
3614
void cleanup_cg(FILE *f)
3615
{
3616
  struct fpconstlist *p;
3617
  unsigned char *ip;
3618
  if(f&&stack_check)
3619
    emit(f,"\t.global\t%s__stack_check\n",idprefix);
3620
  while(p=firstfpc){
3621
    if(f){
3622
      if(section!=RODATA){
3623
        emit(f,rodataname);if(f) section=RODATA;
3624
      }
3625
      emit(f,"%s%d\n\t%s\t",labprefix,p->label,dct[LONG]);
3626
      ip=(unsigned char *)&p->val.vdouble;
3627
      emit(f,"0x%02x%02x%02x%02x",ip[0],ip[1],ip[2],ip[3]);
3628
      if((p->typ&NQ)==DOUBLE||(p->typ&NQ)==LDOUBLE){
3629
        emit(f,",0x%02x%02x%02x%02x",ip[4],ip[5],ip[6],ip[7]);
3630
      }
3631
      emit(f,"\n");
3632
    }
3633
    firstfpc=p->next;
3634
    free(p);
3635
  }
3636
}
3637
 
3638
int reg_parm(struct reg_handle *p,struct Typ *t,int mode,struct Typ *fkt)
3639
{
3640
  if(p->gpr) return 0;
3641
  if(ISSCALAR(t->flags)&&!ISFLOAT(t->flags)&&!ISLWORD(t->flags)){
3642
    p->gpr=1;
3643
    return acc;
3644
  }
3645
  return 0;
3646
}
3647
 
3648
void insert_const(union atyps *p,int t)
3649
/*  Traegt Konstante in entprechendes Feld ein.       */
3650
{
3651
  if(!p) ierror(0);
3652
  t&=NU;
3653
  if(t==BIT) {if(zmeqto(zc2zm(vchar),l2zm(0L))) p->vchar=zm2zc(l2zm(0L)); else p->vchar=zm2zc(l2zm(1L));return;}
3654
  if(t==CHAR) {p->vchar=vchar;return;}
3655
  if(t==SHORT) {p->vshort=vshort;return;}
3656
  if(t==INT) {p->vint=vint;return;}
3657
  if(t==LONG) {p->vlong=vlong;return;}
3658
  if(t==LLONG) {p->vllong=vllong;return;}
3659
  if(t==MAXINT) {p->vmax=vmax;return;}
3660
  if(t==(UNSIGNED|BIT)) {if(zumeqto(zuc2zum(vuchar),ul2zum(0UL))) p->vuchar=zum2zuc(ul2zum(0UL)); else p->vuchar=zum2zuc(ul2zum(1UL));return;}
3661
  if(t==(UNSIGNED|CHAR)) {p->vuchar=vuchar;return;}
3662
  if(t==(UNSIGNED|SHORT)) {p->vushort=vushort;return;}
3663
  if(t==(UNSIGNED|INT)) {p->vuint=vuint;return;}
3664
  if(t==(UNSIGNED|LONG)) {p->vulong=vulong;return;}
3665
  if(t==(UNSIGNED|LLONG)) {p->vullong=vullong;return;}
3666
  if(t==(UNSIGNED|MAXINT)) {p->vumax=vumax;return;}
3667
  if(t==FLOAT) {p->vfloat=vfloat;return;}
3668
  if(t==DOUBLE) {p->vdouble=vdouble;return;}
3669
  if(t==LDOUBLE) {p->vldouble=vldouble;return;}
3670
  if(t==NPOINTER) {p->vuint=vuint;return;}
3671
  if(t==FPOINTER||t==HPOINTER) {p->vulong=vulong;return;}
3672
}
3673
void eval_const(union atyps *p,int t)
3674
/*  Weist bestimmten globalen Variablen Wert einer CEXPR zu.       */
3675
{
3676
  int f=t&NQ;
3677
  if(!p) ierror(0);
3678
  if(f==MAXINT||(f>=BIT&&f<=LLONG)){
3679
    if(!(t&UNSIGNED)){
3680
      if(f==BIT){
3681
        if(zmeqto(zc2zm(p->vchar),l2zm(0L))) vmax=l2zm(0L); else vmax=l2zm(1L);
3682
      }else if(f==CHAR) vmax=zc2zm(p->vchar);
3683
      else if(f==SHORT)vmax=zs2zm(p->vshort);
3684
      else if(f==INT)  vmax=zi2zm(p->vint);
3685
      else if(f==LONG) vmax=zl2zm(p->vlong);
3686
      else if(f==LLONG) vmax=zll2zm(p->vllong);
3687
      else if(f==MAXINT) vmax=p->vmax;
3688
      else ierror(0);
3689
      vumax=zm2zum(vmax);
3690
      vldouble=zm2zld(vmax);
3691
    }else{
3692
      if(f==BIT){
3693
        if(zumeqto(zuc2zum(p->vuchar),ul2zum(0UL))) vumax=ul2zum(0UL); else vumax=ul2zum(1UL);
3694
      }else if(f==CHAR) vumax=zuc2zum(p->vuchar);
3695
      else if(f==SHORT)vumax=zus2zum(p->vushort);
3696
      else if(f==INT)  vumax=zui2zum(p->vuint);
3697
      else if(f==LONG) vumax=zul2zum(p->vulong);
3698
      else if(f==LLONG) vumax=zull2zum(p->vullong);
3699
      else if(f==MAXINT) vumax=p->vumax;
3700
      else ierror(0);
3701
      vmax=zum2zm(vumax);
3702
      vldouble=zum2zld(vumax);
3703
    }
3704
  }else{
3705
    if(ISPOINTER(f)){
3706
      if(f==NPOINTER)
3707
        vumax=zui2zum(p->vuint);
3708
      else
3709
        vumax=zul2zum(p->vulong);
3710
      vmax=zum2zm(vumax);vldouble=zum2zld(vumax);
3711
    }else{
3712
      if(f==FLOAT) vldouble=zf2zld(p->vfloat);
3713
      else if(f==DOUBLE) vldouble=zd2zld(p->vdouble);
3714
      else vldouble=p->vldouble;
3715
      vmax=zld2zm(vldouble);
3716
      vumax=zld2zum(vldouble);
3717
    }
3718
  }
3719
  vfloat=zld2zf(vldouble);
3720
  vdouble=zld2zd(vldouble);
3721
  vuchar=zum2zuc(vumax);
3722
  vushort=zum2zus(vumax);
3723
  vuint=zum2zui(vumax);
3724
  vulong=zum2zul(vumax);
3725
  vullong=zum2zull(vumax);
3726
  vchar=zm2zc(vmax);
3727
  vshort=zm2zs(vmax);
3728
  vint=zm2zi(vmax);
3729
  vlong=zm2zl(vmax);
3730
  vllong=zm2zll(vmax);
3731
}
3732
void printval(FILE *f,union atyps *p,int t)
3733
/*  Gibt atyps aus.                                     */
3734
{
3735
  t&=NU;
3736
  if(t==BIT){vmax=zc2zm(p->vchar);fprintf(f,"B%d",!zmeqto(vmax,l2zm(0L)));}
3737
  if(t==(UNSIGNED|BIT)){vumax=zuc2zum(p->vuchar);fprintf(f,"UB%d",!zumeqto(vmax,ul2zum(0UL)));}
3738
  if(t==CHAR){vmax=zc2zm(p->vchar);printzm(f,vmax);}
3739
  if(t==(UNSIGNED|CHAR)){fprintf(f,"UC");vumax=zuc2zum(p->vuchar);printzum(f,vumax);}
3740
  if(t==SHORT){fprintf(f,"S");vmax=zs2zm(p->vshort);printzm(f,vmax);}
3741
  if(t==(UNSIGNED|SHORT)){fprintf(f,"US");vumax=zus2zum(p->vushort);printzum(f,vumax);}
3742
  if(t==FLOAT){fprintf(f,"F");vldouble=zf2zld(p->vfloat);printzld(f,vldouble);}
3743
  if(t==DOUBLE){fprintf(f,"D");vldouble=zd2zld(p->vdouble);printzld(f,vldouble);}
3744
  if(t==LDOUBLE){fprintf(f,"LD");printzld(f,p->vldouble);}
3745
  if(t==INT){fprintf(f,"I");vmax=zi2zm(p->vint);printzm(f,vmax);}
3746
  if(t==(UNSIGNED|INT)||t==NPOINTER){fprintf(f,"UI");vumax=zui2zum(p->vuint);printzum(f,vumax);}
3747
  if(t==LONG){fprintf(f,"L");vmax=zl2zm(p->vlong);printzm(f,vmax);}
3748
  if(t==(UNSIGNED|LONG)||t==FPOINTER||t==HPOINTER){fprintf(f,"UL");vumax=zul2zum(p->vulong);printzum(f,vumax);}
3749
  if(t==LLONG){fprintf(f,"LL");vmax=zll2zm(p->vllong);printzm(f,vmax);}
3750
  if(t==(UNSIGNED|LLONG)){fprintf(f,"ULL");vumax=zull2zum(p->vullong);printzum(f,vumax);}
3751
  if(t==MAXINT) printzm(f,p->vmax);
3752
  if(t==(UNSIGNED|MAXINT)) printzum(f,p->vumax);
3753
}
3754
void emitval(FILE *f,union atyps *p,int t)
3755
{
3756
  t&=NU;
3757
  if((t&NQ)==NPOINTER) t=(UNSIGNED|INT);
3758
  if(t==BIT){vmax=zc2zm(p->vchar);emit(f,"%d",!zmeqto(vmax,l2zm(0L)));}
3759
  if(t==(UNSIGNED|BIT)){vumax=zuc2zum(p->vuchar);emit(f,"%d",!zumeqto(vmax,ul2zum(0UL)));}
3760
  if(t==CHAR){vmax=zc2zm(p->vchar);emitzm(f,vmax);}
3761
  if(t==(UNSIGNED|CHAR)){vumax=zuc2zum(p->vuchar);emitzum(f,vumax);}
3762
  if(t==SHORT){vmax=zs2zm(p->vshort);emitzm(f,vmax);}
3763
  if(t==(UNSIGNED|SHORT)){vumax=zus2zum(p->vushort);emitzum(f,vumax);}
3764
  if(t==FLOAT){vldouble=zf2zld(p->vfloat);emitzld(f,vldouble);}
3765
  if(t==DOUBLE){vldouble=zd2zld(p->vdouble);emitzld(f,vldouble);}
3766
  if(t==LDOUBLE){emitzld(f,p->vldouble);}
3767
  if(t==INT){vmax=zi2zm(p->vint);emitzm(f,vmax);}
3768
  if(t==(UNSIGNED|INT)||t==NPOINTER){vumax=zui2zum(p->vuint);emitzum(f,vumax);}
3769
  if(t==LONG){vmax=zl2zm(p->vlong);emitzm(f,vmax);}
3770
  if(t==(UNSIGNED|LONG)||t==FPOINTER||t==HPOINTER){vumax=zul2zum(p->vulong);emitzum(f,vumax);}
3771
  if(t==LLONG){vmax=zll2zm(p->vllong);emitzm(f,vmax);}
3772
  if(t==(UNSIGNED|LLONG)){vumax=zull2zum(p->vullong);emitzum(f,vumax);}
3773
  if(t==MAXINT) emitzm(f,p->vmax);
3774
  if(t==(UNSIGNED|MAXINT)) emitzum(f,p->vumax);
3775
}
3776
 
3777
void conv_typ(struct Typ *p)
3778
/* Erzeugt extended types in einem Typ. */
3779
{
3780
  char *attr;
3781
  while(p){
3782
    if(ISPOINTER(p->flags)){
3783
      p->flags=((p->flags&~NU)|POINTER_TYPE(p->next));
3784
      if(attr=p->next->attr){
3785
        if(strstr(attr,STR_NEAR))
3786
          p->flags=((p->flags&~NU)|NPOINTER);
3787
        if(strstr(attr,STR_FAR))
3788
          p->flags=((p->flags&~NU)|FPOINTER);
3789
        if(strstr(attr,STR_HUGE))
3790
          p->flags=((p->flags&~NU)|HPOINTER);
3791
      }
3792
    }
3793
    if(ISINT(p->flags)&&(attr=p->attr)&&strstr(attr,"bit"))
3794
      p->flags=((p->flags&~NU)|BIT);
3795
    p=p->next;
3796
  }
3797
}
3798
 
3799
void init_db(FILE *f)
3800
{
3801
  dwarf2_setup(sizetab[HPOINTER],".byte",".2byte",".4byte",".4byte",labprefix,idprefix,".section");
3802
  dwarf2_print_comp_unit_header(f);
3803
}
3804
void cleanup_db(FILE *f)
3805
{
3806
  dwarf2_cleanup(f);
3807
  if(f) section=-1;
3808
}

powered by: WebSVN 2.1.0

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