blob: 40c6bc9c42fd06562c0de0eae047261ff6e9f52d [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* 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
20static char FILE_[]=__FILE__;
21
22#include "dwarf2.c"
23
24/* Public data that MUST be there. */
25
26/* Name and copyright. */
27char 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 */
30int g_flags[MAXGF]={VALFLAG,VALFLAG,0,0,
31 0,0,0,0,
32 0,0};
33char *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"};
36union ppi g_flags_val[MAXGF];
37
38/* Typenames (needed because of HAVE_EXT_TYPES). */
39char *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
44int bitsperbyte = 8;
45int bytemask = 0xff;
46int dbl_bytemask = 0xffff;
47
48/* Alignment-requirements for all types in bytes. */
49zmax align[MAX_TYPE+1];
50
51/* Alignment that is sufficient for every object. */
52zmax maxalign;
53
54/* CHAR_BIT of the target machine. */
55zmax char_bit;
56
57/* Sizes of all elementary types in bytes. */
58zmax sizetab[MAX_TYPE+1];
59
60/* Minimum and Maximum values each type can have. */
61/* Must be initialized in init_cg(). */
62zmax t_min[MAX_TYPE+1];
63zumax t_max[MAX_TYPE+1];
64zumax tu_max[MAX_TYPE+1];
65
66/* Names of all registers. */
67char *regnames[]={"noreg","d","x","y","sp","u","d/x"};
68
69/* The Size of each register in bytes. */
70zmax regsize[MAXR+1];
71
72/* Type which can store each register. */
73struct 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. */
77int regsa[MAXR+1];
78
79/* Specifies which registers may be scratched by functions. */
80int regscratch[MAXR+1]={0,1,1,0,1,0};
81
82int reg_prio[MAXR+1]={0,0,1,1,0,0};
83
84struct reg_handle empty_reg_handle={0};
85
86/* Names of target-specific variable attributes. */
87char *g_attr_name[]={"__interrupt","__dpage","__far",0};
88#define INTERRUPT 1
89#define DPAGE 2
90#define FAR 4
91
92int MINADDI2P=CHAR;
93
94/****************************************/
95/* Some private data and functions. */
96/****************************************/
97
98static long malign[MAX_TYPE+1]= {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
99static 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
101struct 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
109static int section=-1,newobj,scnt,pushed_acc;
110static 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 */
125static int acc=1,ix=2,iy=3,sp=4,iu=5,dx=6;
126static void pr(FILE *,struct IC *);
127static void function_top(FILE *,struct Var *,long);
128static void function_bottom(FILE *f,struct Var *,long);
129
130static 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
139static long loff,roff,stackoffset,notpopped,dontpop,maxpushed,stack;
140
141static char *x_t[]={"?","","b","","","","","","","","","","","","","",""};
142static char *ccs[]={"eq","ne","lt","ge","le","gt"};
143static char *uccs[]={"eq","ne","lo","hs","ls","hi"};
144static char *logicals[]={"ora","eor","and"};
145static char *dct[]={"",".bit",".byte",".2byte",".2byte",".4byte",".8byte",".4byte",".8byte",".8byte",
146 "(void)",".2byte",".34byte",".34byte"};
147static char *idprefix="",*labprefix=".l";
148static int exit_label,have_frame;
149static char *ret;
150static int stackchecklabel;
151static int frame_used,stack_valid;
152static int CPU=6812;
153static int pcrel,drel;
154static int skip_rel;
155static char *jsrinst="jsr";
156static char *jmpinst="jmp";
157static int nodx,nou;
158int switchsubs;
159
160static int cc_t;
161static struct obj *cc;
162
163static 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
201enum peepf { NEEDSAME = 1, REMOVE1ST = 2, ALLOWSFX = 4};
202struct peeps {char *s1,*s2,*r;enum peepf flags;};
203
204static 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
217static 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
245int 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
489static 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
507static struct fpconstlist {
508 struct fpconstlist *next;
509 int label,typ;
510 union atyps val;
511} *firstfpc;
512
513static 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
536int 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}
555static 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
563static 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
663static 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}
673static 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}
679static 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 */
690static 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 */
723static 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 */
762static void callee_push(long l)
763{
764 if(l-stackoffset>stack)
765 stack=l-stackoffset;
766}
767static void push(long l)
768{
769 stackoffset-=l;
770 if(stackoffset<maxpushed) maxpushed=stackoffset;
771 if(-maxpushed>stack) stack=-maxpushed;
772}
773static void pop(long l)
774{
775 stackoffset+=l;
776}
777static 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}
798static 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}
814static 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}
861static 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}
908static 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*/
921static void clear_ext_ic(struct ext_ic *p)
922{
923 p->flags=0;
924 p->r=0;
925 p->offset=0;
926}
927static 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}
938static 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
1220static 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
1234static 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}
1252static 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}
1277static 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}
1295static 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}
1350static 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}
1364static 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
1422static 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
1440int 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
1646int 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
1660int 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
1689int 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
1703int 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
1757int 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. */
1780char *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
1840int 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
1852void 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
1863void 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
1870void 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
1927void 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
1956static 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. */
2005void 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
3607int 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
3614void 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
3638int 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
3648void 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}
3673void 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}
3732void 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}
3754void 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
3777void 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
3799void 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}
3804void cleanup_db(FILE *f)
3805{
3806 dwarf2_cleanup(f);
3807 if(f) section=-1;
3808}