blob: c8e14b630b2d4ac06a4f27808c5d4391354be55f [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* 6502 backend for vbcc
2 (c) Volker Barthelmann 2020
3
4*/
5
6#include "supp.h"
7#include "vbc.h"
8
9#include <math.h>
10
11static char FILE_[]=__FILE__;
12
13/* Public data that MUST be there. */
14
15/* Name and copyright. */
16char cg_copyright[]="vbcc 6502 code-generator V0.5 (c) in 2022 by Volker Barthelmann";
17
18/* Commandline-flags the code-generator accepts:
19 0: just a flag
20 VALFLAG: a value must be specified
21 STRINGFLAG: a string can be specified
22 FUNCFLAG: a function will be called
23 apart from FUNCFLAG, all other versions can only be specified once */
24int g_flags[MAXGF]={0,0,
25 VALFLAG,0,0,
26 0,0,
27 VALFLAG,VALFLAG,0,0,
28 VALFLAG,0,0,0,
29 0,0,0,
30 0,0,0,0,0,0};
31
32/* the flag-name, do not use names beginning with l, L, I, D or U, because
33 they collide with the frontend */
34char *g_flags_name[MAXGF]={"std-syntax","no-rax",
35 "volatile-regs","ieee","no-peephole",
36 "cbmascii","softstack",
37 "reg-args","int-args","mainargs","no-bank-vars",
38 "common-banknr","btmp-zpage","oldfp","large",
39 "glob-acc","avoid-bank-switch","manual-banking",
40 "atascii","65c02","nox","mega65","ce02","c02",
41 "div-bug","m65io"};
42
43/* the results of parsing the command-line-flags will be stored here */
44union ppi g_flags_val[MAXGF];
45
46/* Alignment-requirements for all types in bytes. */
47zmax align[MAX_TYPE+1];
48
49/* Alignment that is sufficient for every object. */
50zmax maxalign;
51
52/* CHAR_BIT for the target machine. */
53zmax char_bit;
54
55/* sizes of the basic types (in bytes) */
56zmax sizetab[MAX_TYPE+1];
57
58/* Minimum and Maximum values each type can have. */
59/* Must be initialized in init_cg(). */
60zmax t_min[MAX_TYPE+1];
61zumax t_max[MAX_TYPE+1];
62zumax tu_max[MAX_TYPE+1];
63
64/* Names of all registers. will be initialized in init_cg(),
65 register number 0 is invalid, valid registers start at 1 */
66char *regnames[MAXR+1];
67
68/* The Size of each register in bytes. */
69zmax regsize[MAXR+1];
70
71/* a type which can store each register. */
72struct Typ *regtype[MAXR+1];
73
74/* regsa[reg]!=0 if a certain register is allocated and should */
75/* not be used by the compiler pass. */
76int regsa[MAXR+1];
77
78/* Specifies which registers may be scratched by functions. */
79int regscratch[MAXR+1];
80
81/* specifies the priority for the register-allocator, if the same
82 estimated cost-saving can be obtained by several registers, the
83 one with the highest priority will be used */
84int reg_prio[MAXR+1];
85
86/* an empty reg-handle representing initial state */
87struct reg_handle empty_reg_handle={0,0};
88
89/* Names of target-specific variable attributes. */
90char *g_attr_name[]={"__interrupt","__zpage","__nocpr",0};
91
92#define INTERRUPT 1
93#define ZPAGE 2
94#define NOCOMPRESS 4
95
96/****************************************/
97/* Private data and functions. */
98/****************************************/
99
100#define STDSYNTAX (g_flags[0]&USEDFLAG)
101#define NORAX (g_flags[1]&USEDFLAG)
102#define VOL_GPRS ((g_flags[2]&USEDFLAG)?g_flags_val[2].l:NUM_GPRS/2)
103#define IEEE (g_flags[3]&USEDFLAG)
104#define NOPEEP (g_flags[4]&USEDFLAG)
105#define CBMASCII (g_flags[5]&USEDFLAG)
106#define SOFTSTACK (g_flags[6]&USEDFLAG)
107#define GPR_ARGS ((g_flags[7]&USEDFLAG)?g_flags_val[7].l:8)
108#define MAINARGS (g_flags[9]&USEDFLAG)
109#define NOBANKVARS (g_flags[10]&USEDFLAG)
110#define COMMONBANK ((g_flags[11]&USEDFLAG)?g_flags_val[11].l:0)
111#define BIGZPAGE (g_flags[12]&USEDFLAG)
112#define OLDFP (g_flags[13]&USEDFLAG)
113#define LARGE (g_flags[14]&USEDFLAG)
114#define GLOBACC (g_flags[15]&USEDFLAG)
115#define NOSWITCH (g_flags[16]&USEDFLAG)
116#define NOBANKING (g_flags[17]&USEDFLAG)
117#define ATASCII (g_flags[18]&USEDFLAG)
118#define C02 (g_flags[19]&USEDFLAG)
119#define NOX (g_flags[20]&USEDFLAG)
120#define MEGA65 (g_flags[21]&USEDFLAG)
121#define CE02 (g_flags[22]&USEDFLAG)
122#define C02ALT (g_flags[23]&USEDFLAG)
123#define DIVBUG (g_flags[24]&USEDFLAG)
124#define M65IO (g_flags[25]&USEDFLAG)
125
126
127
128#define STR_NEAR "near"
129#define STR_FAR "far"
130#define STR_HUGE "huge"
131
132#define PLA (-1)
133#define JMPIND (-2)
134
135static void function_top(FILE *,struct Var *,long);
136static void function_bottom(FILE *f,struct Var *,long);
137
138#define isreg(x) ((p->x.flags&(REG|DREFOBJ))==REG)
139#define isacc(x) (isreg(x)&&(p->x.reg==ra||p->x.reg==rax))
140#define isconst(x) ((p->x.flags&(KONST|DREFOBJ))==KONST)
141
142#define iszpage(o) (((o)->flags&(REG|DREFOBJ))==REG||(((o)->flags&(VAR|DREFOBJ))==VAR&&(o)->v->tattr&ZPAGE))
143
144#define isptr(r) ((r)>=FIRST_PAIR&&(r)<=LAST_PAIR)
145
146static int q1reg,q2reg,zreg;
147
148static char *ccs[]={"eq","ne","lt","ge","le","gt",""};
149static char *logicals[]={"ora","eor","and"};
150static char *arithmetics[]={"slw","srw","adc","sbc","mullw","divw","mod"};
151
152/* alignment of basic data-types, used to initialize align[] */
153static long malign[MAX_TYPE+1]= {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
154/* sizes of basic data-types, used to initialize sizetab[] */
155static long msizetab[MAX_TYPE+1]={1,1,2,2,4,8,4,4,4,0,2,3,3,0,0,0,1,0};
156static char *mregnames[MAXR+1+4];
157
158/* Typenames (needed because of HAVE_EXT_TYPES). */
159char *typname[]={"strange","char","short","int","long","long long",
160 "float","double","long double","void",
161 "near-pointer","far-pointer","huge-pointer",
162 "array","struct","union","enum","function"};
163
164
165/* used to initialize regtyp[] */
166static struct Typ ityp={INT},ctyp={CHAR},ftyp={FLOAT},lltyp={LLONG};
167
168/* macros defined by the backend */
169static char *marray[]={"__section(x)=__vattr(\"section(\"#x\")\")",
170 "__6502__",
171 "__SIZE_T_INT",
172 "__bank(x)=__vattr(\"bank(\"#x\")\")",
173 "__far=__attr(\"far\")",
174 "__near=__attr(\"near\")",
175 "__huge=__attr(\"huge\")",
176 0};
177
178/* special registers */
179static int ra=1, rx=2, ry=3, sp1=4,sp2=5,sp=6,fp,fp1,fp2;
180static int t4=LAST_GPR,t3=LAST_GPR-1,t2=LAST_GPR-2,t1=LAST_GPR-3;
181static int rax=7;
182static int yval;
183#define NOVAL 1000
184
185#define REGDUMMY1 MAXR+1
186#define REGDUMMY2 MAXR+2
187#define REGDUMMY3 MAXR+3
188
189static int t1,t2,f1,f2; /*tODO: remove*/
190
191static int pushedacc,pushedx,nopeep,cbmascii,atascii,ieee;
192static int storedacc,storedx;
193static int c02,m65,ce02,zzero,noy;
194static int divbug;
195static int m65io;
196static int manbank;
197static char *jmpinst;
198static int pass;
199static int libsave;
200static struct rpair rp2;
201static int cbank;
202static Var bankv;
203static int bankvoffset;
204static int bankcnum;
205static obj zstore;
206static int zstoreflag;
207static int hasretval;
208
209#define SECLEN 128
210char *use_sec;
211int use_bank=-1;
212
213#define dt(t) (((t)&UNSIGNED)?udt[(t)&NQ]:sdt[(t)&NQ])
214static char *sdt[MAX_TYPE+1]={"??","c","s","i","l","ll","f","d","ld","v","p"};
215static char *udt[MAX_TYPE+1]={"??","uc","us","ui","ul","ull","f","d","ld","v","p"};
216
217/* perhaps provide version with 8bit int? */
218#define ISCHAR(t) ((t&NQ)==CHAR)
219#define ISSHORT(t) ((t&NQ)==SHORT||(t&NQ)==INT||(t&NQ)==POINTER)
220#define ISFPOINTER(t) ((t&NQ)==FPOINTER)
221#define ISLONG(t) ((t&NQ)==LONG)
222#define ISLLONG(t) ((t&NQ)==LLONG)
223
224#define ISIDX(r) (r==rx)
225#define ISRIDX(op) (isreg(op)&&ISIDX(p->op.reg))
226#define ISPREG(op) (isreg(op)&&isptr(p->op.reg))
227
228#define LONGM65(c) ((c)==ASSIGN||(c)==PUSH||(c)==GETRETURN||(c)==SETRETURN||((c)>=LSHIFT&&(c)<=MOD)||((c)>=OR&&(c)<=AND))
229
230/* am */
231#define IMM_IND 1
232#define GPR_IND 2
233#define ABS_IND 3
234
235/* sections */
236#define DATA 0
237#define BSS 1
238#define CODE 2
239#define RODATA 3
240#define SPECIAL 4
241
242static long stack;
243static int stack_valid;
244static int section=-1,newobj;
245static char *codename="\tsection\ttext",
246 *dataname="\tsection\tdata",
247 *bssname="\tsection\tbss",
248 *rodataname="\tsection\trodata";
249
250/* return-instruction */
251static char *ret;
252
253/* label at the end of the function (if any) */
254static int exit_label;
255
256/* assembly-prefixes for labels and external identifiers */
257static char *labprefix="l",*idprefix="_";
258
259/* variables to calculate the size and partitioning of the stack-frame
260 in the case of FIXED_SP */
261static long frameoffset,pushed,maxpushed,framesize;
262
263static long localsize,rsavesize,rscnt,argsize;
264
265static void emit_obj(FILE *f,struct obj *p,int t);
266
267/* calculate the actual current offset of an object relativ to the
268 stack-pointer; we use a layout like this:
269 ------------------------------------------------
270 | arguments to this function |
271 ------------------------------------------------
272 | caller-save registers [size=rsavesize] |
273 ------------------------------------------------
274 | local variables [size=localsize] |
275 ------------------------------------------------
276 | arguments to called functions [size=argsize] |
277 ------------------------------------------------
278 All sizes will be aligned as necessary.
279 In the case of FIXED_SP, the stack-pointer will be adjusted at
280 function-entry to leave enough space for the arguments and have it
281 aligned to 16 bytes. Therefore, when calling a function, the
282 stack-pointer is always aligned to 16 bytes.
283 For a moving stack-pointer, the stack-pointer will usually point
284 to the bottom of the area for local variables, but will move while
285 arguments are put on the stack.
286
287 This is just an example layout. Other layouts are also possible.
288*/
289
290#define bank(x) bankx((x),manbank)
291#define sbank(x) bankx((x),0)
292
293static int bankx(Var *v,int nobank)
294{
295 char *s=v->vattr;
296 int n,r;
297 if(!nobank&&s&&(s=strstr(s,"bank("))){
298 if(sscanf(s+5,"%i",&n)==1)
299 return n;
300 }
301 return -1;
302}
303
304static void ebank(FILE *f,int b)
305{
306 if(b>=0) emit(f,"%d",b);
307 emit(f,"\n");
308}
309
310static long real_offset(struct obj *o)
311{
312 long off=zm2l(o->v->offset);
313 if(off<0){
314 /* function parameter */
315 off=localsize+rsavesize-off-zm2l(maxalign);
316 }
317
318 off+=argsize;
319 off+=zm2l(o->val.vmax);
320 return off;
321}
322
323/* Initializes an addressing-mode structure and returns a pointer to
324 that object. Will not survive a second call! */
325static struct obj *cam(int flags,int base,long offset)
326{
327 static struct obj obj;
328 static struct AddressingMode am;
329 obj.am=&am;
330 am.flags=flags;
331 am.base=base;
332 am.offset=offset;
333 return &obj;
334}
335
336/* changes to a special section, used for __section() */
337static int special_section(FILE *f,struct Var *v)
338{
339 char *sec;
340 if(v->tattr&ZPAGE){
341 emit(f,"\tsection\tzpage\n");
342 }else{
343 if(!v->vattr) return 0;
344 sec=strstr(v->vattr,"section(");
345 if(!sec) return 0;
346 sec+=strlen("section(");
347 emit(f,"\tsection\t");
348 while(*sec&&*sec!=')') emit_char(f,*sec++);
349 emit(f,"\n");
350 }
351 if(f) section=SPECIAL;
352 return 1;
353}
354
355
356
357#define chk_coll(x) do{if((x)==r||(x)==r1||(x)==r2) return 0; \
358 if(reg_pair((x),&rp)&&(rp.r1==r||rp.r2==r)) return 0;}while(0)
359
360static int scratch(IC *p,int r,int isnext)
361{
362 int r1,r2;
363 if(!p) return 1;
364 if(reg_pair(r,&rp)){
365 r1=rp.r1;
366 r2=rp.r2;
367 }else{
368 r1=0;
369 r2=0;
370 }
371 if(!isnext&&isreg(z)&&p->z.reg==r){
372 if(!(p->q2.flags&REG))
373 return 1;
374 if(p->q2.reg==r||p->q2.reg==r1||p->q2.reg==r2)
375 return 0;
376 if(reg_pair(p->q2.reg,&rp))
377 if(rp.r1==r||rp.r2==r)
378 return 0;
379 return 1;
380 }
381 while(p){
382 if(p->code==LABEL||p->code==CALL)
383 return 0;
384 if(p->code>=BEQ&&p->code<=BRA)
385 return 0;
386 if(p->code==FREEREG||p->code==ALLOCREG){
387 if(p->q1.reg==r)
388 return 1;
389 if(reg_pair(p->q1.reg,&rp)&&(rp.r1==r||rp.r2==r))
390 return 1;
391 }
392 if(p->q1.am){
393 chk_coll(p->q1.am->base);
394 if(p->q1.am->flags!=IMM_IND) chk_coll(p->q1.am->idx);
395 }
396 if(p->q2.am){
397 chk_coll(p->q2.am->base);
398 if(p->q2.am->flags!=IMM_IND) chk_coll(p->q2.am->idx);
399 }
400 if(p->z.am){
401 chk_coll(p->z.am->base);
402 if(p->z.am->flags!=IMM_IND) chk_coll(p->z.am->idx);
403 }
404 if(p->q1.flags&REG) chk_coll(p->q1.reg);
405 if(p->q2.flags&REG) chk_coll(p->q2.reg);
406 if(p->z.flags&REG){
407 if(p->z.flags&DREFOBJ)
408 chk_coll(p->z.reg);
409 else{
410 if(p->z.reg==r)
411 return 1;
412 if(reg_pair(p->z.reg,&rp)&&(rp.r1==r||rp.r2==r))
413 return 1;
414 }
415 }
416
417 p=p->next;
418 }
419 return 1;
420}
421
422static int rsavecur;
423static int in_isr;
424
425static int get_reg(FILE *f,IC *p,int t)
426{
427 int r,r1,r2,pass,flag;
428
429 for(pass=0;pass<5;pass++){
430 for(r=MAXR;r>sp;r--){
431 if(reg_pair(r,&rp)){
432 r1=rp.r1;
433 r2=rp.r2;
434 }else{
435 r1=0;
436 r2=0;
437 }
438 if((pass==0||pass==3)&&(!regscratch[r]||in_isr))
439 continue;
440 if(pass<3){
441 if(regs[r]) continue;
442 if(r1&&(regs[r1]||regs[r2])) continue;
443 }
444 if(pass==2&&!(regs[r]&4))
445 continue;
446 if(p->q1.flags&REG){
447 if(p->q1.reg==r||p->q1.reg==r1||p->q1.reg==r2) continue;
448 if(r1==0&&reg_pair(p->q1.reg,&rp)&&(rp.r1==r||rp.r2==r)) continue;
449 }
450 if(p->q2.flags&REG){
451 if(p->q2.reg==r||p->q2.reg==r1||p->q2.reg==r2) continue;
452 if(r1==0&&reg_pair(p->q2.reg,&rp)&&(rp.r1==r||rp.r2==r)) continue;
453 }
454 if(p->z.flags&REG){
455 if(p->z.reg==r||p->z.reg==r1||p->z.reg==r2) continue;
456 if(r1==0&&reg_pair(p->z.reg,&rp)&&(rp.r1==r||rp.r2==r)) continue;
457 }
458 if(regok(r,t,1)){
459 flag=8;
460 if(regs[r]){
461 flag|=2;
462 if(p->code==COMPARE||p->code==TEST)
463 ierror(0);
464 if(regs[ra]){
465 emit(f,"\ttay\n");
466 yval=NOVAL;
467 }
468 if(r1){
469 emit(f,"\tlda\t%s\n",mregnames[r1]);
470 emit(f,"\tpha\n");
471 emit(f,"\tlda\t%s\n",mregnames[r2]);
472 emit(f,"\tpha\n");
473 }else{
474 emit(f,"\tlda\t%s\n",mregnames[r]);
475 emit(f,"\tpha\n");
476 }
477 if(regs[ra])
478 emit(f,"\ttya\n");
479 }
480 if(r1){
481 regs[r1]|=flag;
482 regs[r2]|=flag;
483 }
484 regs[r]|=flag;
485 regused[r]=1;
486 regused[r1]=1;
487 regused[r2]=1;
488 /*emit(f,"; p=%p r=%s\n",(void*)p,mregnames[r]);*/
489 return r;
490 }
491 }
492 }
493 pric2(stdout,p);
494 ierror(0);
495}
496
497static void get_acc(FILE *f, IC *p,int t)
498{
499 int r;
500 if(isacc(z)) return;
501 t&=NQ;
502 if(ISCHAR(t)){
503 if(1/*!isreg(q1)||(p->q1.reg!=ra&&p->q1.reg!=rax)*/){
504 if((regs[ra]||regs[rax])&&!scratch(p,ra,0)&&!pushedacc){
505 if(storedacc)
506 pushedacc=storedacc;
507 else if(optsize||(regs[t1]&&regs[t2]&&regs[t3]&&regs[t4])){
508 emit(f,"\tpha\n");
509 pushedacc=-1;
510 }else{
511 r=get_reg(f,p,CHAR);
512 emit(f,"\tsta\t%s\n",mregnames[r]);
513 pushedacc=r;
514 }
515 }
516 }
517 }else{
518 if(1/*!isreg(q1)||p->q1.reg!=rax*/){
519 if((regs[ra]||regs[rax])&&(!scratch(p,ra,0)||!scratch(p,rax,0))&&!pushedacc){
520 if(!storedacc){
521 r=get_reg(f,p,CHAR);
522 emit(f,"\tsta\t%s\n",mregnames[r]);
523 pushedacc=r;
524 }else
525 pushedacc=storedacc;
526 }
527 if((regs[rx]||regs[rax])&&!scratch(p,rax,0)&&!pushedx){
528 if(!storedx){
529 r=get_reg(f,p,CHAR);
530 emit(f,"\tstx\t%s\n",mregnames[r]);
531 pushedx=r;
532 }else
533 pushedx=storedx;
534 }
535 }
536 }
537}
538
539static int cmp_get_acc(FILE *f,IC *p,IC *branch)
540{
541 if(!regs[ra]&&!regs[rax])
542 return 0;
543 if(branch==0&&pushedacc)
544 return 0;
545 if(branch&&isreg(q1)&&(p->q1.reg==ra||p->q1.reg==rax))
546 if(branch->code==BEQ||branch->code==BNE||(p->typf&UNSIGNED))
547 return 0;
548 if(scratch(p,ra,0))
549 return 0;
550 if(!regs[rx]&&!regs[rax]){
551 emit(f,"\ttax\n");
552 pushedacc=rx;
553 }
554 emit(f,"\tpha\n");
555 pushedacc=-1;
556 return pushedacc;
557}
558
559static void reload_acc_opt(FILE *f,IC *p)
560{
561 if(pushedacc==0) return;
562 if(pushedacc>0){
563 while(p){
564 if(p->code!=FREEREG) break;
565 if(p->q1.reg==ra||p->q1.reg==rax){
566 pushedacc=0;
567 return;
568 }
569 p=p->next;
570 }
571 }
572 if(pushedacc==-1)
573 emit(f,"\tpla\n");
574 else if(pushedacc==rx)
575 emit(f,"\ttxa\n");
576 else if(pushedacc==ry)
577 emit(f,"\ttya\n");
578 else if(pushedacc){
579 emit(f,"\tlda\t%s\n",mregnames[pushedacc]);
580 regs[pushedacc]&=~8;
581 }
582 pushedacc=0;
583}
584
585static void reload_acc(FILE *f)
586{
587 reload_acc_opt(f,0);
588}
589
590static void push(int i)
591{
592 pushed-=i;
593 if(pushed<maxpushed)
594 maxpushed=pushed;
595}
596
597static void pop(int i)
598{
599 pushed+=i;
600 if(pushed>0) ierror(0);
601}
602
603static int indirect(obj *o)
604{
605 if(o->am){
606 if(o->am->flags==ABS_IND&&o->am->idx==rx)
607 return 0;
608 else
609 return 1;
610 }
611 if((o->flags&(DREFOBJ|KONST))==DREFOBJ)
612 return 1;
613 if((o->flags&(REG|VAR))!=VAR){
614 if((o->flags&REG)&&(o->reg==ra||ISIDX(o->reg)||o->reg==rax))
615 return 1;
616 return 0;
617 }
618 if(o->v->storage_class==AUTO||o->v->storage_class==REGISTER)
619 return 1;
620 return 0;
621}
622
623void convfloat(void)
624{
625}
626
627void sety(FILE *f,int val)
628{
629 if(yval==val)
630 return;
631 if(val-yval==1)
632 emit(f,"\tiny\n");
633 else if(yval-val==1)
634 emit(f,"\tdey\n");
635 else{
636 emit(f,"\tldy\t#%d\n",val);
637 if(val<0||val>255)
638 ierror(0);
639 }
640 yval=val;
641}
642
643static void cnv_fp(void)
644{
645 double d,mant;
646 int exp;
647 unsigned long t;
648
649 if(ieee){
650 vfloat=zld2zf(vldouble);
651 memcpy((void*)&vmax,(void*)&vfloat,4);
652 }else{
653 d=zld2d(vldouble);
654 mant=frexp(d,&exp);
655 exp=(exp+127)&255;
656 t=((unsigned long)(mant*8388608))&0xffffff;
657 t|=((long)exp)<<24;
658
659 t=((t&0xff)<<24)|((t&0xff00)<<8)|((t&0xff0000)>>8)|((t&0xff000000)>>24);
660 vmax=l2zm((long)t);
661 if(mant==0&&d==0) vmax=Z0;
662 }
663}
664
665static void emit_ieee(FILE *f,union atyps *p,int t)
666{
667 unsigned char *ip=(unsigned char *)&p->vdouble;
668 emit(f,"0x%02x%02x,0x%02x%02x",ip[1],ip[0],ip[3],ip[2]);
669 if(t==DOUBLE||t==LDOUBLE)
670 emit(f,",0x%02x%02x,0x%02x%02x",ip[5],ip[4],ip[7],ip[6]);
671 emit(f,"\n");
672}
673
674static void emit_lobyte(FILE *f,obj *o,int t)
675{
676 if(o->flags&KONST){
677 if(o->flags&DREFOBJ){
678 eval_const(&o->val,o->dtyp);
679 emit(f,"%d",zm2l(vmax));
680 }else{
681 eval_const(&o->val,t);
682 if(ISFLOAT(t)) cnv_fp();
683 emit(f,"#%d",zm2l(vmax)&255);
684 }
685 }else if(o->flags&VARADR){
686 emit(f,"#<(");
687 emit_obj(f,o,t);
688 emit(f,")");
689 }else if((o->flags&(REG|DREFOBJ))==REG){
690 if(!reg_pair(o->reg,&rp))
691 emit(f,"%s",mregnames[o->reg]);
692 else
693 emit(f,"%s",mregnames[rp.r1]);
694 }else{
695 if(zzero&&(o->flags&(DREFOBJ|KONST))==DREFOBJ) noy=1;
696 emit_obj(f,o,t);
697 noy=0;
698 }
699}
700
701static void emit_hibyte(FILE *f,obj *o,int t)
702{
703 if(o->flags&KONST){
704 if(o->flags&DREFOBJ){
705 eval_const(&o->val,o->dtyp);
706 emit(f,"%d",zm2l(vmax)+1);
707 }else{
708 eval_const(&o->val,t);
709 if(ISFLOAT(t)) cnv_fp();
710 emit(f,"#%d",(zm2l(vmax)>>8)&255);
711 }
712 }else if(o->flags&VARADR){
713 emit(f,"#>(");
714 emit_obj(f,o,t);
715 emit(f,")");
716 }else if((o->flags&(REG|DREFOBJ))==REG){
717 if(o->reg>=FIRST_BIG&&o->reg<=LAST_BIGP){
718 emit(f,"%s+1",mregnames[o->reg]);
719 }else{
720 if(!reg_pair(o->reg,&rp))
721 ierror(0);
722 emit(f,"%s",mregnames[rp.r2]);
723 }
724 }else{
725 if(o->flags&VARADR)
726 emit(f,"#");
727 if(!(o->flags&DREFOBJ))
728 o->val.vmax=zmadd(o->val.vmax,Z1);
729 emit_obj(f,o,t);
730 if(!(o->flags&DREFOBJ))
731 o->val.vmax=zmsub(o->val.vmax,Z1);
732 }
733}
734
735static void emit_byte3(FILE *f,obj *o,int t)
736{
737 if(o->flags&KONST){
738 if(o->flags&DREFOBJ){
739 eval_const(&o->val,o->dtyp);
740 emit(f,"%d",zm2l(vmax)+2);
741 }else{
742 eval_const(&o->val,t);
743 if(ISFLOAT(t)) cnv_fp();
744 emit(f,"#%d",(zm2l(vmax)>>16)&255);
745 }
746 }else if((o->flags&(REG|DREFOBJ))==REG){
747 emit(f,"%s+2",mregnames[o->reg]);
748 }else if(o->flags&VARADR){
749 emit(f,"#%d",bank(o->v));
750 }else{
751 if(!(o->flags&DREFOBJ))
752 o->val.vmax=zmadd(o->val.vmax,l2zm(2L));
753 emit_obj(f,o,t);
754 if(!(o->flags&DREFOBJ))
755 o->val.vmax=zmsub(o->val.vmax,l2zm(2L));
756 }
757}
758
759static void emit_byte4(FILE *f,obj *o,int t)
760{
761 if(o->flags&KONST){
762 if(o->flags&DREFOBJ){
763 eval_const(&o->val,o->dtyp);
764 emit(f,"%d",zm2l(vmax)+3);
765 }else{
766 eval_const(&o->val,t);
767 if(ISFLOAT(t)) cnv_fp();
768 emit(f,"#%d",(zm2l(vmax)>>24)&255);
769 }
770 }else if((o->flags&(REG|DREFOBJ))==REG){
771 emit(f,"%s+3",mregnames[o->reg]);
772 }else{
773 if(!(o->flags&DREFOBJ))
774 o->val.vmax=zmadd(o->val.vmax,l2zm(3L));
775 emit_obj(f,o,t);
776 if(!(o->flags&DREFOBJ))
777 o->val.vmax=zmsub(o->val.vmax,l2zm(3L));
778 }
779}
780
781static void ldq_offset(FILE *f,obj *o)
782{
783 if(o->am){
784 if(o->am->flags==IMM_IND)
785 emit(f,"\tldz\t#%ld\n",o->am->offset);
786 else if(o->am->flags==GPR_IND||o->am->flags==ABS_IND){
787 if(o->am->idx==ra)
788 emit(f,"\ttaz\n");
789 else{
790 if(ISIDX(o->am->idx)){
791 if(o->am->flags==GPR_IND){
792 emit(f,"\tpha\n");
793 emit(f,"\tt%sa\n",mregnames[o->am->idx]);
794 emit(f,"\ttaz\n");
795 emit(f,"\tpla\n");
796 }
797 }else
798 emit(f,"\tldz\t%s\n",mregnames[o->am->idx]);
799 }
800 }else
801 ierror(0);
802 }else if((o->flags&(DREFOBJ|KONST))==DREFOBJ){
803 /*if(!zzero)*/ emit(f,"\tldz\t#0\n");
804 }else if((o->flags&(VAR|REG|VARADR))==VAR&&(o->v->storage_class==AUTO||o->v->storage_class==REGISTER)){
805 emit(f,"\tldz\t#%ld\n",real_offset(o));
806 }
807}
808
809static void do_amload(FILE *f,obj *o)
810{
811 if(o->am->flags==GPR_IND||o->am->flags==ABS_IND){
812 if(o->am->idx==ra)
813 emit(f,"\ttay\n");
814 else{
815 if(ISIDX(o->am->idx)){
816 if(o->am->flags==GPR_IND){
817 emit(f,"\tpha\n");
818 emit(f,"\tt%sa\n",mregnames[o->am->idx]);
819 emit(f,"\ttay\n");
820 emit(f,"\tpla\n");
821 }
822 }else{
823 if(o->am->idx==ra)
824 emit(f,"\ttay\n");
825 else
826 emit(f,"\tldy\t%s\n",mregnames[o->am->idx]);
827 }
828 }
829 }else
830 ierror(0);
831}
832static void do_lobyte(FILE *f,char *s,obj *o,int type)
833{
834 if(o->am){
835 if(o->am->flags==IMM_IND)
836 sety(f,o->am->offset);
837 else{
838 do_amload(f,o);
839 yval=NOVAL;
840 }
841 }else if((o->flags&(DREFOBJ|KONST))==DREFOBJ){
842 if(!zzero) sety(f,0);
843 }else if((o->flags&(VAR|REG|VARADR))==VAR&&(o->v->storage_class==AUTO||o->v->storage_class==REGISTER)){
844 sety(f,(int)real_offset(o));
845 }
846 emit(f,"\t%s\t",s);
847 emit_lobyte(f,o,type);
848 emit(f,"\n");
849}
850
851static void do_hibyte(FILE *f,char *s,obj *o,int type)
852{
853 int ami=0;
854 if(o->am){
855 if(o->am->flags==IMM_IND)
856 sety(f,o->am->offset+1);
857 else{
858 do_amload(f,o);
859 if(o->am->flags==GPR_IND){
860 emit(f,"\tiny\n");
861 }else{
862 o->am->offset++;ami=1;
863 }
864 yval=NOVAL;
865 }
866 }else if((o->flags&(DREFOBJ|KONST))==DREFOBJ){
867 sety(f,1);
868 }else if((o->flags&(VAR|REG|VARADR))==VAR&&(o->v->storage_class==AUTO||o->v->storage_class==REGISTER)){
869 sety(f,(int)real_offset(o)+1);
870 }
871 emit(f,"\t%s\t",s);
872 emit_hibyte(f,o,type);
873 emit(f,"\n");
874 if(ami) o->am->offset--;
875}
876
877static void do_byte3(FILE *f,char *s,obj *o,int type)
878{
879 int ami=0;
880 if(o->am){
881 if(o->am->flags==IMM_IND)
882 sety(f,o->am->offset+2);
883 else{
884 do_amload(f,o);
885 if(o->am->flags==GPR_IND){
886 emit(f,"\tiny\n\tiny\n");
887 }else{
888 o->am->offset+=2;ami=1;
889 }
890 yval=NOVAL;
891 }
892 }else if((o->flags&(DREFOBJ|KONST))==DREFOBJ){
893 sety(f,2);
894 }else if((o->flags&(VAR|REG|VARADR))==VAR&&(o->v->storage_class==AUTO||o->v->storage_class==REGISTER)){
895 sety(f,(int)real_offset(o)+2);
896 }
897 emit(f,"\t%s\t",s);
898 emit_byte3(f,o,type);
899 emit(f,"\n");
900 if(ami) o->am->offset-=2;
901}
902
903static void do_byte4(FILE *f,char *s,obj *o,int type)
904{
905 int ami=0;
906 if(o->am){
907 if(o->am->flags==IMM_IND)
908 sety(f,o->am->offset+3);
909 else{
910 do_amload(f,o);
911 if(o->am->flags==GPR_IND){
912 emit(f,"\tiny\n\tiny\n\tiny\n");
913 }else{
914 o->am->offset+=3;ami=1;
915 }
916 yval=NOVAL;
917 }
918 }else if((o->flags&(DREFOBJ|KONST))==DREFOBJ){
919 sety(f,3);
920 }else if((o->flags&(VAR|REG|VARADR))==VAR&&(o->v->storage_class==AUTO||o->v->storage_class==REGISTER)){
921 sety(f,(int)real_offset(o)+3);
922 }
923 emit(f,"\t%s\t",s);
924 emit_byte4(f,o,type);
925 emit(f,"\n");
926 if(ami) o->am->offset-=3;
927}
928
929static void load_lobyte(FILE *f,obj *o,int t)
930{
931 if((o->flags&(REG|DREFOBJ))==REG){
932 if(o->reg==ra||o->reg==rax)
933 return;
934 if(o->reg==rx){
935 emit(f,"\ttxa\n");
936 return;
937 }
938 }
939 do_lobyte(f,"lda",o,t);
940}
941
942static void load_hibyte(FILE *f,obj *o,int t)
943{
944 if((o->flags&REG)&&(o->reg==rx||o->reg==rax))
945 emit(f,"\ttxa\n");
946 else
947 do_hibyte(f,"lda",o,t);
948}
949
950static void store_lobyte(FILE *f,obj *o,int t)
951{
952 if((o->flags&(REG|DREFOBJ))==REG){
953 if(o->reg==ra||o->reg==rax)
954 return;
955 if(o->reg==rx){
956 emit(f,"\ttax\n");
957 return;
958 }
959 }
960 do_lobyte(f,"sta",o,t);
961}
962
963static void store_hibyte(FILE *f,obj *o,int t)
964{
965 if((o->flags&REG)&&(o->reg==rx||o->reg==rax))
966 emit(f,"\ttax\n");
967 else
968 do_hibyte(f,"sta",o,t);
969}
970
971static void load_acc(FILE *f,obj *o,int type)
972{
973 if((o->flags&REG)&&(o->reg==ra||o->reg==rax))
974 return;
975 if(!ISCHAR(type)){
976 if(indirect(o)){
977 do_hibyte(f,"lda",o,type);
978 emit(f,"\ttax\n");
979 }else
980 do_hibyte(f,"ldx",o,type);
981 }
982 if((o->flags&(REG|DREFOBJ))==REG&&o->reg==rx)
983 emit(f,"\ttxa\n");
984 else
985 do_lobyte(f,"lda",o,type);
986}
987
988static void store_acc(FILE *f,obj *o,int type)
989{
990 if((o->flags&(DREFOBJ|KONST))==DREFOBJ&&((!(o->flags&REG))||!isptr(o->reg))){
991 ierror(0);
992 }
993 if((o->flags&REG)&&(o->reg==ra||o->reg==rax))
994 return;
995 if((o->flags&REG)&&o->reg==rx){
996 emit(f,"\ttax\n");
997 return;
998 }
999 store_lobyte(f,o,type);
1000 if(!ISCHAR(type)){
1001 if(indirect(o)){
1002 /*TODO: save accu */
1003 emit(f,"\ttxa\n");
1004 store_hibyte(f,o,type);
1005 }else
1006 do_hibyte(f,"stx",o,type);
1007 }
1008}
1009
1010static void load_reg(FILE *f,int r,struct obj *o,int type)
1011{
1012 static obj ro;
1013 if(ISIDX(r)&&!indirect(o)){
1014 static char ldr[4]="ldr";
1015 ldr[2]=mregnames[r][0];
1016 do_lobyte(f,ldr,o,type);
1017 return;
1018 }
1019 ro.flags=REG;
1020 ro.reg=r;
1021 load_lobyte(f,o,type);
1022 store_lobyte(f,&ro,type);
1023 if(!ISCHAR(type)){
1024 load_hibyte(f,o,type);
1025 store_hibyte(f,&ro,type);
1026 }
1027}
1028
1029static void store_reg(FILE *f,int r,struct obj *o,int type)
1030{
1031 static obj ro;
1032 if(ISIDX(r)){
1033 if((o->flags&(REG|DREFOBJ))==REG){
1034 if(o->reg==r)
1035 return;
1036 if(o->reg==ra){
1037 emit(f,"\tt%sa\n",mregnames[r]);
1038 return;
1039 }
1040 }
1041 if(!indirect(o)){
1042 static char str[4]="str";
1043 str[2]=mregnames[r][0];
1044 do_lobyte(f,str,o,type);
1045 return;
1046 }
1047 }
1048 ro.flags=REG;
1049 ro.reg=r;
1050 if(r!=ra&&r!=rax)
1051 load_acc(f,&ro,type);
1052 store_acc(f,o,type);
1053}
1054
1055static struct fpconstlist {
1056 struct fpconstlist *next;
1057 int label;
1058 int t;
1059 union atyps val;
1060} *firstfpc;
1061
1062static int addfpconst(struct obj *o,int t)
1063{
1064 struct fpconstlist *p=firstfpc;
1065 t&=NQ;
1066 if(t==LDOUBLE) t=DOUBLE;
1067 for(p=firstfpc;p;p=p->next){
1068 if(t==p->t){
1069 eval_const(&p->val,t);
1070 if(t==FLOAT&&zldeqto(vldouble,zf2zld(o->val.vfloat))) return p->label;
1071 if(t==DOUBLE&&zldeqto(vldouble,zd2zld(o->val.vdouble))) return p->label;
1072 if(t==LONG&&zmeqto(vmax,zl2zm(o->val.vlong))) return p->label;
1073 if(t==LLONG&&zmeqto(vmax,zll2zm(o->val.vllong))) return p->label;
1074 }
1075 }
1076 p=mymalloc(sizeof(struct fpconstlist));
1077 p->next=firstfpc;
1078 p->t=t;
1079 p->label=++label;
1080 p->val=o->val;
1081 firstfpc=p;
1082 return p->label;
1083}
1084
1085/* generate code to load the address of a local variable into register r */
1086static void load_laddr(FILE *f,int r,struct obj *o)
1087{
1088 long l=real_offset(o);
1089 /* assumes acc is available */
1090 if(!reg_pair(r,&rp)) ierror(0);
1091 emit(f,"\tlda\t%s\n",mregnames[fp]);
1092 if(l!=0)
1093 emit(f,"\tclc\n");
1094 if(l&255)
1095 emit(f,"\tadc\t#%ld\n",l&255);
1096 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
1097 emit(f,"\tlda\t%s\n",mregnames[fp2]);
1098 if(l!=0)
1099 emit(f,"\tadc\t#%ld\n",(l>>8)&255);
1100 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
1101}
1102
1103/* generate code to load the address of a variable into register r */
1104static void load_address(FILE *f,int r,struct obj *o,int t)
1105{
1106 if(o->flags&DREFOBJ){
1107 o->flags&=~DREFOBJ;
1108 load_reg(f,r,o,POINTER);
1109 o->flags|=DREFOBJ;
1110 }else if((o->flags&(REG|DREFOBJ))==REG){
1111 if(!reg_pair(r,&rp)) ierror(0);
1112 emit(f,"\tlda\t#>%s\n",mregnames[o->reg]);
1113 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
1114 emit(f,"\tlda\t#<%s\n",mregnames[o->reg]);
1115 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
1116 }else if(o->flags&VAR){
1117 if(o->v->storage_class==AUTO||o->v->storage_class==REGISTER){
1118 load_laddr(f,r,o);
1119 }else{
1120 o->flags|=VARADR;
1121 load_reg(f,r,o,POINTER);
1122 o->flags&=~VARADR;
1123 }
1124 }else if((o->flags&(KONST|DREFOBJ))==KONST){
1125 int l=addfpconst(o,t);
1126 if(!ieee) ierror(0);
1127 if(!reg_pair(r,&rp)) ierror(0);
1128 emit(f,"\tlda\t#>%s%d\n",labprefix,l);
1129 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
1130 emit(f,"\tlda\t#<%s%d\n",labprefix,l);
1131 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
1132 }else
1133 ierror(0);
1134}
1135
1136
1137/* Yields log2(x)+1 or 0. */
1138static long pof2(zumax x)
1139{
1140 zumax p;int ln=1;
1141 p=ul2zum(1L);
1142 while(ln<=32&&zumleq(p,x)){
1143 if(zumeqto(x,p)) return ln;
1144 ln++;p=zumadd(p,p);
1145 }
1146 return 0;
1147}
1148
1149static void incmem(FILE *f,obj *o,int t,int op,int x)
1150{
1151 int i,idx=0;
1152 char *s;
1153 if(ce02&&ISSHORT(t)){
1154 if(((o->flags&(REG|DREFOBJ))==REG&&(op==ADD||op==SUB))||
1155 (op==LSHIFT&&!indirect(o)&&!o->am)){
1156 do{
1157 emit(f,"\t%s\t%s\n",op==ADD?"inw":(op==SUB?"dew":"asw"),mregnames[o->reg]);
1158 }while(--x);
1159 return;
1160 }
1161 }
1162 if((o->flags&(REG|DREFOBJ))==REG&&ISIDX(o->reg)){
1163 static char buf[4]=" ";
1164 idx=1;s=buf;
1165 if(op==ADD){s[0]='i';s[1]='n';}else{s[0]='d';s[1]='e';}
1166 s[2]=mregnames[o->reg][0];
1167 }else if(op==ADD)
1168 s="inc";
1169 else if(op==SUB)
1170 s="dec";
1171 else if(op==LSHIFT)
1172 s="asl";
1173 else if(op==RSHIFT&&(t&UNSIGNED))
1174 s="lsr";
1175 else if(op==RSHIFT){
1176 s="cmp\t#128\n\tror";
1177 }else
1178 ierror(0);
1179 if(ISCHAR(t)){
1180 for(i=0;i<x;i++){
1181 if(idx){
1182 emit(f,"\t%s\n",s);
1183 }else{
1184 emit(f,"\t%s\t",s);
1185 emit_obj(f,o,t);
1186 emit(f,"\n");
1187 }
1188 }
1189 }else{
1190 for(i=0;i<x;i++){
1191 if(op==SUB){
1192 if(m65&&ISLONG(t)){
1193 emit(f,"\tdeq\t");
1194 emit_obj(f,o,t);
1195 emit(f,"\n");
1196 }else if(ce02&&iszpage(o)){
1197 emit(f,"\tdew\n");
1198 }else{
1199 /* caller mus make sure accu is available */
1200 load_lobyte(f,o,t);
1201 emit(f,"\tbne\t%s%d\n",labprefix,++label);
1202 emit(f,"\tdec\t");
1203 emit_hibyte(f,o,t);
1204 emit(f,"\n");
1205 if(ISLONG(t)){
1206 ierror(0);
1207 }
1208 emit(f,"%s%d:\n",labprefix,label);
1209 emit(f,"\tdec\t");
1210 emit_lobyte(f,o,t);
1211 emit(f,"\n");
1212 }
1213 }else if(op==ADD){
1214 if(!optspeed&&m65&&ISLONG(t)){
1215 emit(f,"\tinq\t");
1216 emit_obj(f,o,t);
1217 emit(f,"\n");
1218 }else if(!optspeed&&ce02&&iszpage(o)){
1219 emit(f,"\tinw\t");
1220 emit_lobyte(f,o,t);
1221 emit(f,"\n");
1222 if(ISLONG(t)){
1223 emit(f,"\tbne\t%s%d\n",labprefix,++label);
1224 emit(f,"\tinw\t");
1225 emit_byte3(f,o,t);
1226 emit(f,"\n");
1227 emit(f,"%s%d:\n",labprefix,label);
1228 }
1229 }else{
1230 emit(f,"\t%s\t",s);
1231 emit_lobyte(f,o,t);
1232 emit(f,"\n");
1233 emit(f,"\tbne\t%s%d\n",labprefix,++label);
1234 emit(f,"\t%s\t",s);
1235 emit_hibyte(f,o,t);
1236 emit(f,"\n");
1237 if(ISLONG(t)){
1238 emit(f,"\tbne\t%s%d\n",labprefix,label);
1239 emit(f,"\t%s\t",s);
1240 emit_byte3(f,o,t);
1241 emit(f,"\n");
1242 emit(f,"\tbne\t%s%d\n",labprefix,label);
1243 emit(f,"\t%s\t",s);
1244 emit_byte4(f,o,t);
1245 emit(f,"\n");
1246 }
1247 emit(f,"%s%d:\n",labprefix,label);
1248 }
1249 }else if(op==LSHIFT){
1250 if(ce02&&!indirect(o)&&!o->am){
1251 emit(f,"\tasw\t");
1252 emit_obj(f,o,t);
1253 emit(f,"\n");
1254 }else{
1255 emit(f,"\tasl\t");
1256 emit_lobyte(f,o,t);
1257 emit(f,"\n");
1258 emit(f,"\trol\t");
1259 emit_hibyte(f,o,t);
1260 emit(f,"\n");
1261 }
1262 if(ISLONG(t)){
1263 do_byte3(f,"rol",o,t);
1264 do_byte4(f,"rol",o,t);
1265 }
1266 }else if(op==RSHIFT&&(t&UNSIGNED)){
1267 /*emit(f,"\tclc\n");
1268 emit(f,"\tror\t");*/
1269 if(ISLONG(t)){
1270 do_byte4(f,"lsr",o,t);
1271 do_byte3(f,"ror",o,t);
1272 do_hibyte(f,"ror",o,t);
1273 }else
1274 do_hibyte(f,"lsr",o,t);
1275 do_lobyte(f,"ror",o,t);
1276 }else if(op==RSHIFT){
1277 if(ce02){
1278 emit(f,"\tasr\t");
1279 }else{
1280 if(ISLONG(t))
1281 do_byte4(f,"lda",o,t);
1282 else
1283 load_hibyte(f,o,t);
1284 emit(f,"\tcmp\t#128\n");
1285 emit(f,"\tror\t");
1286 }
1287 if(ISLONG(t))
1288 emit_byte4(f,o,t);
1289 else
1290 emit_hibyte(f,o,t);
1291 emit(f,"\n");
1292 if(ISLONG(t)){
1293 do_byte3(f,"ror",o,t);
1294 do_hibyte(f,"ror",o,t);
1295 }
1296 do_lobyte(f,"ror",o,t);
1297 }else{
1298 printf("op=%d\n",op);
1299 ierror(0);
1300 }
1301 }
1302 }
1303}
1304
1305static void preload_obj(FILE *f,IC *p,obj *o)
1306{
1307 int r,pa=0,px=0,longm65=0;long of;
1308
1309 if((p->typf&VOLATILE)||(p->typf2&VOLATILE)||
1310 ((p->q1.flags&DREFOBJ)&&(p->q1.dtyp&(VOLATILE|PVOLATILE)))||
1311 ((p->q2.flags&DREFOBJ)&&(p->q2.dtyp&(VOLATILE|PVOLATILE)))||
1312 ((p->z.flags&DREFOBJ)&&(p->z.dtyp&(VOLATILE|PVOLATILE))))
1313 emit(f,"; volatile barrier\n");
1314
1315
1316 if(m65){
1317 int t;
1318 if(o==&p->q1)
1319 t=q1typ(p);
1320 else{
1321 if(o==&p->q2) t=q2typ(p);
1322 else if(o==&p->z) t=ztyp(p);
1323 else ierror(0);
1324 if(ISLONG(t)&&LONGM65(p->code)) longm65=1;
1325 }
1326 }
1327
1328 if((o->flags&(VAR|REG))==VAR&&(o->v->storage_class==AUTO||o->v->storage_class==REGISTER)&&(((of=real_offset(o))+zm2l(szof(o->v->vtyp))>255)||longm65)){
1329 r=get_reg(f,p,POINTER);
1330 if(o->flags&DREFOBJ){
1331 if(p->code==GETRETURN&&(p->q1.reg==ra||p->q1.reg==rax)){
1332 emit(f,"\tsta\t%s\n",mregnames[t1]);
1333 emit(f,"\tstx\t%s\n",mregnames[t2]);
1334 pa=px=1;
1335 }else
1336 get_acc(f,p,INT);
1337 }else{
1338 if(p->code==GETRETURN&&(p->q1.reg==ra||p->q1.reg==rax)){
1339 emit(f,"\tsta\t%s\n",mregnames[t1]);
1340 pa=1;
1341 }else
1342 cmp_get_acc(f,p,0);
1343 }
1344 if(!reg_pair(r,&rp)) ierror(0);
1345 emit(f,"\tlda\t%s\n",mregnames[fp1]);
1346 emit(f,"\tclc\n");
1347 if(of&0xff)
1348 emit(f,"\tadc\t#%ld\n",of&0xff);
1349 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
1350 emit(f,"\tlda\t%s\n",mregnames[fp2]);
1351 if(1/*of&0xff00*/)
1352 emit(f,"\tadc\t#%ld\n",(of>>8)&0xff);
1353 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
1354 o->flags|=REG;
1355 o->reg=r;
1356 if(o->flags&DREFOBJ){
1357 if(!zzero) sety(f,0);
1358 emit(f,"\tlda\t(%s)%s\n",mregnames[r],zzero?"":",y");
1359 emit(f,"\ttxa\n");
1360 sety(f,1);
1361 emit(f,"\tlda\t(%s),y\n",mregnames[r]);
1362 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
1363 emit(f,"\tstx\t%s\n",mregnames[rp.r1]);
1364 }else{
1365 o->flags|=DREFOBJ;
1366 o->dtyp=POINTER;
1367 }
1368 if(pa){ emit(f,"\tlda\t%s\n",mregnames[t1]); pa=0;}
1369 if(px){ emit(f,"\tldx\t%s\n",mregnames[t2]); px=0;}
1370 }
1371
1372 if((o->flags&(DREFOBJ|KONST))==DREFOBJ&&(!(o->flags&REG)||!isptr(o->reg))&&(!(o->flags&VAR)||!(o->v->tattr&ZPAGE))&&!ISFPOINTER(o->dtyp)){
1373 if(p->code==GETRETURN&&(p->q1.reg==ra||p->q1.reg==rax)){
1374 emit(f,"\tsta\t%s\n",mregnames[t1]);
1375 pa=1;
1376 }else
1377 cmp_get_acc(f,p,0);
1378 r=get_reg(f,p,POINTER);
1379 o->flags&=~DREFOBJ;
1380 load_reg(f,r,o,POINTER);
1381 o->flags|=REG|DREFOBJ;
1382 o->reg=r;
1383 if(pa){ emit(f,"\tlda\t%s\n",mregnames[t1]); pa=0;}
1384 }
1385}
1386
1387static void far_copy(FILE *f,IC *p)
1388{
1389 int b;long l;
1390 get_acc(f,p,INT);
1391 if(p->code==PUSH){
1392 if(!reg_pair(LAST_PAIR,&rp)) ierror(0);
1393 emit(f,"\tlda\t%s\n",mregnames[sp]);
1394 if(pushed) emit(f,"\tclc\n");
1395 if(pushed&0xff) emit(f,"\tadc\t#%d\n",(pushed&0xff));
1396 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
1397 emit(f,"\tlda\t%s+1\n",mregnames[sp]);
1398 if(pushed) emit(f,"\tadc\t#%d\n",((pushed>>8)&0xff));
1399 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
1400 pushed+=zm2l(p->q2.val.vmax);
1401 emit(f,"\tldx\t#%d\n",bankcnum);
1402 }else if(p->z.flags&DREFOBJ){
1403 if(!reg_pair(LAST_PAIR,&rp)) ierror(0);
1404 p->z.flags&=~DREFOBJ;
1405 load_lobyte(f,&p->z,FPOINTER);
1406 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
1407 load_hibyte(f,&p->z,FPOINTER);
1408 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
1409 if(indirect(&p->z)){
1410 do_byte3(f,"lda",&p->z,FPOINTER);
1411 emit(f,"\ttax\n");
1412 }else
1413 do_byte3(f,"ldx",&p->z,FPOINTER);
1414 }else{
1415 load_address(f,LAST_PAIR,&p->z,POINTER);
1416 b=bank(p->z.v);
1417 emit(f,"\tldx\t#%d\n",b>=0?b:bankcnum);
1418 }
1419 if(p->q1.flags&DREFOBJ){
1420 if(!reg_pair(LAST_PAIR-1,&rp)) ierror(0);
1421 p->q1.flags&=~DREFOBJ;
1422 load_lobyte(f,&p->q1,FPOINTER);
1423 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
1424 load_hibyte(f,&p->q1,FPOINTER);
1425 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
1426 if(indirect(&p->q1)){
1427 do_byte3(f,"lda",&p->q1,FPOINTER);
1428 emit(f,"\ttay\n");
1429 }else
1430 do_byte3(f,"ldy",&p->q1,FPOINTER);
1431 }else{
1432 load_address(f,LAST_PAIR-1,&p->q1,POINTER);
1433 b=bank(p->q1.v);
1434 sety(f,b>=0?b:bankcnum);
1435 }
1436 l=zm2l(p->q2.val.vmax);
1437 emit(f,"\tlda\t#%d\n",(l>>8)&0xff);
1438 emit(f,"\tsta\t%s__bankcopy_len+1\n",idprefix);
1439 emit(f,"\tlda\t#%d\n",(l)&0xff);
1440 emit(f,"\tsta\t%s__bankcopy_len\n",idprefix);
1441 emit(f,"\tlda\t#%d\n",cbank>=0?cbank:bankcnum);
1442 emit(f,"\tjsr\t%s__bankcopy\n",idprefix);
1443 yval=NOVAL;
1444}
1445
1446static void load_far(FILE *f,IC *p,obj *o,int t)
1447{
1448 int pushed=0;
1449 if(!(o->flags&DREFOBJ)) ierror(0);
1450 o->flags&=~DREFOBJ;
1451 t&=NQ;
1452 if(zmeqto(sizetab[t],Z0)) return;
1453 /*get_acc(f,p,INT);*/
1454 if(pushedacc==t3||pushedacc==t4) ierror(0);
1455 if(pushedx==t3||pushedx==t4) ierror(0);
1456 if(regs[ra]||regs[rax]){
1457 if(isacc(q1)||isacc(q2)||!isacc(z)){
1458 pushed=1;
1459 emit(f,"\tpha\n");
1460 if(regs[rax]) emit(f,"\ttxa\n\tpha\n");
1461 }
1462 }
1463 load_reg(f,LAST_PAIR,o,POINTER);
1464 if(!indirect(o))
1465 do_byte3(f,"ldy",o,CHAR);
1466 else{
1467 do_byte3(f,"lda",o,CHAR);
1468 emit(f,"\ttay\n");
1469 }
1470 emit(f,"\tldx\t#%d\n",bankvoffset);
1471 emit(f,"\tlda\t#%d\n",cbank>=0?cbank:bankcnum);
1472 emit(f,"\tjsr\t%s__bankload%d\n",idprefix,(int)zm2l(sizetab[t]));
1473 yval=NOVAL;
1474 o->flags=VAR;
1475 o->v=&bankv;
1476 o->val.vmax=l2zm((long)bankvoffset);
1477 bankvoffset+=zm2l(sizetab[t]);
1478 if(pushed){
1479 if(regs[rax]) emit(f,"\tpla\n\ttax\n");
1480 emit(f,"\tpla\n");
1481 }
1482}
1483
1484static void load_banked(FILE *f,IC *p,obj *o,int t)
1485{
1486 int pushed=0,m;
1487 if(o->flags&DREFOBJ) t=o->dtyp;
1488 t&=NQ;
1489 if(zmeqto(sizetab[t],Z0)) return;
1490 /*get_acc(f,p,INT);*/
1491 if(pushedacc==t3||pushedacc==t4) ierror(0);
1492 if(pushedx==t3||pushedx==t4) ierror(0);
1493 if(regs[ra]||regs[rax]){
1494 if(isacc(q1)||isacc(q2)||!isacc(z)){
1495 pushed=1;
1496 emit(f,"\tpha\n");
1497 if(regs[rax]||regs[rx]) emit(f,"\ttxa\n\tpha\n");
1498 }
1499 }
1500 m=o->flags;
1501 o->flags&=~DREFOBJ;
1502 load_address(f,LAST_PAIR,o,POINTER);
1503 o->flags=m;
1504 emit(f,"\tldx\t#%d\n",bankvoffset);
1505 emit(f,"\tlda\t#%d\n",cbank>=0?cbank:bankcnum);
1506 sety(f,bank(o->v));
1507 emit(f,"\tjsr\t%s__bankload%d\n",idprefix,(int)zm2l(sizetab[t]));
1508 yval=NOVAL;
1509 o->v=&bankv;
1510 o->val.vmax=l2zm((long)bankvoffset);
1511 bankvoffset+=zm2l(sizetab[t]);
1512 if(pushed){
1513 if(regs[rax]||regs[rx]) emit(f,"\tpla\n\ttax\n");
1514 emit(f,"\tpla\n");
1515 }
1516}
1517
1518static void preload(FILE *f,IC *p)
1519{
1520 int r,mra=regs[ra],mrax=regs[rax];
1521 int bq1=-1,bq2=-1,bz=-1,sb=-1,zbuf=0;
1522
1523 if(((p->q1.flags&DREFOBJ)&&p->q1.am&&(p->q1.am->flags==GPR_IND||p->q1.am->flags==ABS_IND)&&p->q1.am->idx==ra)||
1524 ((p->q2.flags&DREFOBJ)&&p->q2.am&&(p->q2.am->flags==GPR_IND||p->q2.am->flags==ABS_IND)&&p->q2.am->idx==ra)||
1525 ((p->z.flags&DREFOBJ)&&p->z.am&&(p->z.am->flags==GPR_IND||p->z.am->flags==ABS_IND)&&p->z.am->idx==ra)
1526 ){
1527 if(pushedacc>0)
1528 r=pushedacc;
1529 else{
1530 r=get_reg(f,p,CHAR);
1531 emit(f,"\tsta\t%s\n",mregnames[r]);
1532 }
1533 pushedacc=r;
1534 if((p->q1.flags&DREFOBJ)&&p->q1.am&&(p->q1.am->flags==GPR_IND||p->q1.am->flags==ABS_IND)&&p->q1.am->idx==ra)
1535 p->q1.am->idx=r;
1536 if((p->q2.flags&DREFOBJ)&&p->q2.am&&(p->q2.am->flags==GPR_IND||p->q2.am->flags==ABS_IND)&&p->q2.am->idx==ra)
1537 p->q2.am->idx=r;
1538 if((p->z.flags&DREFOBJ)&&p->z.am&&(p->z.am->flags==GPR_IND||p->z.am->flags==ABS_IND)&&p->z.am->idx==ra)
1539 p->z.am->idx=r;
1540 }
1541
1542 if(p->code==GETRETURN&&p->q1.reg==ra&&!regs[ra])
1543 regs[ra]=1;
1544
1545 if(p->code==GETRETURN&&p->q1.reg==rax&&!regs[rax])
1546 regs[rax]=1;
1547
1548 bankvoffset=0;
1549
1550 if(!NOBANKVARS){
1551 if((p->q1.flags&(VAR|VARADR))==VAR) bq1=bank(p->q1.v);
1552 if((p->q2.flags&(VAR|VARADR))==VAR) bq2=bank(p->q2.v);
1553 if((p->z.flags&(VAR|VARADR))==VAR) bz=bank(p->z.v);
1554
1555 if((p->q1.flags&(VAR|VARADR))==(VAR|VARADR)){
1556 r=bank(p->q1.v);
1557 /*if(r>=0&&r!=cbank) ierror(0);*/
1558 }
1559
1560 if((p->code==ASSIGN||p->code==PUSH)&&!zmleq(p->q2.val.vmax,l2zm(4L))){
1561 if(p->q1.flags&DREFOBJ) preload_obj(f,p,&p->q1);
1562 if(p->z.flags&DREFOBJ) preload_obj(f,p,&p->z);
1563 return;
1564 }
1565
1566 if(p->code!=CALL){
1567 /* TODO: some optimizations possible */
1568 if(bq1>=0&&bq1!=cbank){
1569 if(cbank<0&&!NOSWITCH)
1570 sb=bq1;
1571 else
1572 load_banked(f,p,&p->q1,q1typ(p));
1573 }
1574 if(bq2>=0&&bq2!=cbank){
1575 if((bq2==sb||(cbank<0&&sb<0))&&!NOSWITCH)
1576 sb=bq2;
1577 else
1578 load_banked(f,p,&p->q2,q2typ(p));
1579 }
1580 if(bz>=0&&bz!=cbank&&(p->z.flags&DREFOBJ)){
1581 if((bz==sb||(cbank<0&&sb<0))||!NOSWITCH)
1582 sb=bz;
1583 else
1584 load_banked(f,p,&p->z,ztyp(p));
1585 }
1586
1587 if(sb>=0){
1588 if(NOSWITCH) ierror(0);
1589 sety(f,sb);
1590 emit(f,"\tjsr\t%s__bankswitch\n",idprefix);
1591 yval=NOVAL;
1592 }
1593 }
1594 }
1595
1596 if((p->q1.flags&DREFOBJ)&&ISFPOINTER(p->q1.dtyp)&&p->code!=CALL) load_far(f,p,&p->q1,q1typ(p));
1597 if((p->q2.flags&DREFOBJ)&&ISFPOINTER(p->q2.dtyp)) load_far(f,p,&p->q2,q2typ(p));
1598
1599 if(isacc(q2)){
1600 static obj o;
1601 int t=q2typ(p);
1602 r=get_reg(f,p,t);
1603 o.flags=REG;
1604 o.reg=r;
1605 store_acc(f,&o,t);
1606 p->q2.reg=r;
1607 if(!pushedacc){
1608 if((t&NQ)==CHAR)
1609 storedacc=r;
1610 else{
1611 if(!reg_pair(r,&rp)) ierror(0);
1612 storedacc=rp.r1;
1613 storedx=rp.r2;
1614 }
1615 }
1616 }
1617
1618 if((p->code==ADDI2P||p->code==SUBIFP)&&ISRIDX(q2)){
1619 static obj o;
1620 if(p->q2.reg==rx){
1621 if(pushedx>0) r=pushedx;
1622 else if(storedx>0) r=storedx;
1623 else r=get_reg(f,p,CHAR);
1624 }else
1625 r=get_reg(f,p,CHAR);
1626 o.flags=REG;
1627 o.reg=r;
1628 store_reg(f,p->q2.reg,&o,CHAR);
1629 p->q2.reg=r;
1630 storedx=r;
1631 }
1632
1633 if(p->code!=ADDRESS){
1634 preload_obj(f,p,&p->q1);
1635 if((p->q1.flags&(DREFOBJ|VAR|REG))==(DREFOBJ|VAR|REG)&&
1636 (p->q2.flags&(DREFOBJ|VAR|REG))==(DREFOBJ|VAR)&&
1637 p->q1.v==p->q2.v){
1638 p->q2.flags|=REG;
1639 p->q2.reg=p->q1.reg;
1640 }
1641 if((p->q1.flags&(DREFOBJ|VAR|REG))==(DREFOBJ|VAR|REG)&&
1642 (p->z.flags&(DREFOBJ|VAR|REG))==(DREFOBJ|VAR)&&
1643 p->q1.v==p->z.v){
1644 p->z.flags|=REG;
1645 p->z.reg=p->q1.reg;
1646 }
1647 }
1648
1649 preload_obj(f,p,&p->q2);
1650 if((p->q2.flags&(DREFOBJ|VAR|REG))==(DREFOBJ|VAR|REG)&&
1651 (p->z.flags&(DREFOBJ|VAR|REG))==(DREFOBJ|VAR)&&
1652 p->q2.v==p->z.v){
1653 p->z.flags|=REG;
1654 p->z.reg=p->q2.reg;
1655 }
1656
1657
1658 if((p->z.flags&DREFOBJ)&&ISFPOINTER(p->z.dtyp)) zbuf=1;
1659 if((p->z.flags&(VAR|DREFOBJ))==VAR){
1660 bz=bank(p->z.v);
1661 if(bz>=0&&bz!=cbank) zbuf=1;
1662 }
1663
1664 if(zbuf&&!NOBANKVARS){
1665 zstore=p->z;
1666 p->z.flags=VAR;
1667 p->z.v=&bankv;
1668 p->z.val.vmax=l2zm((long)bankvoffset);
1669 zstoreflag=1;
1670 /*bankvoffset+=zm2l(sizetab[p->typf&NQ]);*/
1671 }else{
1672 preload_obj(f,p,&p->z);
1673
1674 if(isreg(z)){
1675 r=0;
1676 if(p->q1.am&&p->q1.am->base==p->z.reg){
1677 r=get_reg(f,p,POINTER);
1678 cmp_get_acc(f,p,0);
1679 if(!reg_pair(p->q1.am->base,&rp)) ierror(0);
1680 if(!reg_pair(r,&rp2)) ierror(0);
1681 emit(f,"\tlda\t%s\n",mregnames[rp.r1]);
1682 emit(f,"\tsta\t%s\n",mregnames[rp2.r1]);
1683 emit(f,"\tlda\t%s\n",mregnames[rp.r2]);
1684 emit(f,"\tsta\t%s\n",mregnames[rp2.r2]);
1685 p->q1.am->base=p->q1.reg=r;
1686 }else if(!p->q1.am&&(p->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p->q1.reg==p->z.reg){
1687 r=get_reg(f,p,POINTER);
1688 cmp_get_acc(f,p,0);
1689 if(!reg_pair(p->z.reg,&rp)) ierror(0);
1690 if(!reg_pair(r,&rp2)) ierror(0);
1691 emit(f,"\tlda\t%s\n",mregnames[rp.r1]);
1692 emit(f,"\tsta\t%s\n",mregnames[rp2.r1]);
1693 emit(f,"\tlda\t%s\n",mregnames[rp.r2]);
1694 emit(f,"\tsta\t%s\n",mregnames[rp2.r2]);
1695 p->q1.reg=r;
1696 }
1697 if(p->q2.am&&p->q2.am->base==p->z.reg){
1698 if(r==0){
1699 r=get_reg(f,p,POINTER);
1700 cmp_get_acc(f,p,0);
1701 if(!reg_pair(p->q2.am->base,&rp)) ierror(0);
1702 if(!reg_pair(r,&rp2)) ierror(0);
1703 emit(f,"\tlda\t%s\n",mregnames[rp.r1]);
1704 emit(f,"\tsta\t%s\n",mregnames[rp2.r1]);
1705 emit(f,"\tlda\t%s\n",mregnames[rp.r2]);
1706 emit(f,"\tsta\t%s\n",mregnames[rp2.r2]);
1707 }
1708 p->q2.am->base=p->q2.reg=r;
1709 }else if(!p->q2.am&&(p->q2.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p->q2.reg==p->z.reg){
1710 if(r==0){
1711 r=get_reg(f,p,POINTER);
1712 cmp_get_acc(f,p,0);
1713 if(!reg_pair(p->z.reg,&rp)) ierror(0);
1714 if(!reg_pair(r,&rp2)) ierror(0);
1715 emit(f,"\tlda\t%s\n",mregnames[rp.r1]);
1716 emit(f,"\tsta\t%s\n",mregnames[rp2.r1]);
1717 emit(f,"\tlda\t%s\n",mregnames[rp.r2]);
1718 emit(f,"\tsta\t%s\n",mregnames[rp2.r2]);
1719 }
1720 p->q2.reg=r;
1721 }
1722 }
1723 if(isacc(z)){
1724 if(isacc(q2)){
1725 if(p->q2.reg==rax){
1726 r=get_reg(f,p,INT);
1727 if(!reg_pair(r,&rp)) ierror(0);
1728 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
1729 emit(f,"\tstx\t%s\n",mregnames[rp.r2]);
1730 storedacc=rp.r1;
1731 storedx=rp.r2;
1732 }else{
1733 r=get_reg(f,p,CHAR);
1734 emit(f,"\tsta\t%s\n",mregnames[r]);
1735 storedacc=r;
1736 }
1737 p->q2.reg=r;
1738 if(isacc(q1))
1739 p->q1.reg=r;
1740 }
1741 }
1742 }
1743
1744 reload_acc(f);
1745
1746 regs[ra]=mra;
1747 regs[rax]=mrax;
1748}
1749
1750
1751/* compare if two objects are the same */
1752static int compare_objects(struct obj *o1,struct obj *o2)
1753{
1754 if((o1->flags&(REG|DREFOBJ))==REG&&(o2->flags&(REG|DREFOBJ))==REG&&o1->reg==o2->reg)
1755 return 1;
1756 if(o1->flags==o2->flags){
1757 if(o1->am){
1758 if(o2->am){
1759 if(o1->am->flags!=o2->am->flags||o1->am->base!=o2->am->base||
1760 o1->am->idx!=o2->am->idx||o1->am->offset!=o2->am->offset)
1761 return 0;
1762 else
1763 return 1;
1764 }else
1765 return 0;
1766 }else if(o2->am)
1767 return 0;
1768 if(!(o1->flags&VAR)||(o1->v==o2->v&&zmeqto(o1->val.vmax,o2->val.vmax))){
1769 if(!(o1->flags&REG)||o1->reg==o2->reg){
1770 return 1;
1771 }
1772 }
1773 }
1774 return 0;
1775}
1776
1777/* save the result (in zreg) into p->z */
1778void save_result(FILE *f,struct IC *p)
1779{
1780 ierror(0);
1781}
1782
1783/* prints an object */
1784static void emit_obj(FILE *f,struct obj *p,int t)
1785{
1786 if(p->am){
1787 if(p->am->flags==IMM_IND)
1788 emit(f,"(%s),y ;am(%ld)",mregnames[p->am->base],p->am->offset);
1789 else if(p->am->flags==GPR_IND)
1790 emit(f,"(%s),y ;am(%s)",mregnames[p->am->base],mregnames[p->am->idx]);
1791 else if(p->am->flags==ABS_IND){
1792 emit(f,"%ld",p->am->offset);
1793 if(p->am->v){
1794 Var *v=p->am->v;
1795 if(v->storage_class==EXTERN)
1796 emit(f,"+%s%s",idprefix,v->identifier);
1797 else
1798 emit(f,"+%s%ld",labprefix,zm2l(v->offset));
1799 }
1800 if(ISIDX(p->am->idx))
1801 emit(f,",%s ;am(%s)",mregnames[p->am->idx],mregnames[p->am->idx]);
1802 else
1803 emit(f,",y ;am(%s)",mregnames[p->am->idx]);
1804 }else
1805 ierror(0);
1806 return;
1807 }
1808 if((p->flags&(KONST|DREFOBJ))==(KONST|DREFOBJ)){
1809 emitval(f,&p->val,p->dtyp&NU);
1810 return;
1811 }
1812 if(p->flags&DREFOBJ) emit(f,"(");
1813 if(p->flags&REG){
1814 emit(f,"%s",mregnames[p->reg]);
1815 }else if(p->flags&VAR) {
1816 if(p->v->storage_class==AUTO||p->v->storage_class==REGISTER)
1817 emit(f,"(%s),%s",mregnames[fp],noy==2?"z":"y");
1818 else{
1819 if(!zmeqto(l2zm(0L),p->val.vmax)){emitval(f,&p->val,MAXINT);emit(f,"+");}
1820 if(p->v->storage_class==STATIC){
1821 emit(f,"%s%ld",labprefix,zm2l(p->v->offset));
1822 }else{
1823 emit(f,"%s%s",idprefix,p->v->identifier);
1824 }
1825 }
1826 }
1827 if(p->flags&KONST){
1828 if(/*ieee&&((t&NQ)==DOUBLE||(t&NQ)==LDOUBLE)*/ISFLOAT(t))
1829 emit(f,"%s%d",labprefix,addfpconst(p,t));
1830 else
1831 emitval(f,&p->val,t&NU);
1832 }
1833 if(p->flags&DREFOBJ) emit(f,")%s",noy==0?",y":(noy==1?"":",z"));
1834}
1835
1836/* Test if there is a sequence of FREEREGs containing FREEREG reg.
1837 Used by peephole. */
1838static int exists_freereg(struct IC *p,int reg)
1839{
1840 while(p&&(p->code==FREEREG||p->code==ALLOCREG)){
1841 if(p->code==FREEREG&&p->q1.reg==reg) return 1;
1842 p=p->next;
1843 }
1844 return 0;
1845}
1846
1847/* search for possible addressing-modes */
1848static void peephole(struct IC *p)
1849{
1850 int c,c2,r;struct IC *p2,*free_base,*use;struct AddressingMode *am;
1851
1852 for(;p;p=p->next){
1853 c=p->code;
1854 if(c!=FREEREG&&c!=ALLOCREG&&(c!=SETRETURN||!isreg(q1)||p->q1.reg!=p->z.reg)) exit_label=0;
1855 if(c==LABEL) exit_label=p->typf;
1856
1857 /* Try const(reg) */
1858 if((c==ADDI2P||c==SUBIFP)&&ISPREG(z)&&(p->q2.flags&(KONST|DREFOBJ))==KONST&&!ISFPOINTER(p->typf2)){
1859 int base;zmax of;struct obj *o;IC *dub=0;
1860 eval_const(&p->q2.val,p->typf);
1861 if(c==SUBIFP) of=zmsub(l2zm(0L),vmax); else of=vmax;
1862 if(zmleq(Z0,of)&&zmleq(of,l2zm(255L))){
1863 r=p->z.reg;
1864 if(isreg(q1)&&isptr(p->q1.reg)) base=p->q1.reg; else base=r;
1865 o=0;free_base=0;
1866 for(p2=p->next;p2;p2=p2->next){
1867 c2=p2->code;
1868 if(c2==CALL||c2==LABEL||(c2>=BEQ&&c2<=BRA)) break;
1869 if(c2==FREEREG&&p2->q1.reg==p->z.reg) free_base=p2;
1870 if(c2!=FREEREG&&(p2->q1.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==r) break;
1871 if(c2!=FREEREG&&(p2->q2.flags&(REG|DREFOBJ))==REG&&p2->q2.reg==r) break;
1872 if(c2!=CALL&&(c2<LABEL||c2>BRA)/*&&c2!=ADDRESS*/){
1873 int t,mc;
1874 if((c2==ASSIGN|c2==PUSH)&&(p2->typf&NQ)==CHAR&&!zmeqto(p2->q2.val.vmax,Z1))
1875 mc=1;
1876 else
1877 mc=0;
1878 if(!o&&(c2==ADD||c2==SUB||c2==AND||c2==OR||c2==XOR)&&/*(p2->typf&NQ)==CHAR&&*/!p2->q1.am&&!p2->z.am&&
1879 (p2->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&
1880 p2->q1.flags==p2->z.flags&&p2->q1.reg==r&&p2->z.reg==r){
1881 o=&p2->q1;use=p2;
1882 dub=p2;
1883 continue;
1884 }
1885 if(!p2->q1.am&&(p2->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->q1.reg==r){
1886 if(o||mc) break;
1887 t=q1typ(p2)&NQ;
1888 if(t>POINTER||ISFLOAT(t)) break;
1889 if(m65&&ISLONG(t)) break;
1890 o=&p2->q1;use=p2;
1891 }
1892 if(!p2->q2.am&&(p2->q2.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->q2.reg==r){
1893 if(o||mc) break;
1894 t=q2typ(p2)&NQ;
1895 if(t>POINTER||ISFLOAT(t)) break;
1896 if(m65&&ISLONG(t)) break;
1897 o=&p2->q2;use=p2;
1898 }
1899 if(!p2->z.am&&(p2->z.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->z.reg==r){
1900 if(o||mc) break;
1901 t=ztyp(p2)&NQ;
1902 if(t>POINTER||ISFLOAT(t)) break;
1903 if(m65&&ISLONG(t)) break;
1904 o=&p2->z;use=p2;
1905 }
1906 }
1907 if(c2==FREEREG||(p2->z.flags&(REG|DREFOBJ))==REG){
1908 int m;
1909 if(c2==FREEREG)
1910 m=p2->q1.reg;
1911 else{
1912 m=p2->z.reg;
1913 if(o==&p->q1||o==&p->q2) break;
1914 }
1915 if(m==r){
1916 if(o){
1917 o->am=am=mymalloc(sizeof(*am));
1918 am->flags=IMM_IND;
1919 am->base=base;
1920 am->offset=(int)zm2l(of);
1921 if(ISPREG(q1)){
1922 p->code=c=NOP;p->q1.flags=p->q2.flags=p->z.flags=0;
1923 }else{
1924 p->code=c=ASSIGN;p->q2.flags=0;
1925 p->typf=p->typf2;p->q2.val.vmax=sizetab[p->typf2&NQ];
1926 }
1927 }
1928 if(dub){
1929 dub->z=*o;
1930 dub->z.am=mymalloc(sizeof(*am));
1931 *dub->z.am=*o->am;
1932 }
1933 if(free_base) move_IC(use,free_base);
1934 break;
1935 }
1936 if(c2!=FREEREG&&m==base) break;
1937 continue;
1938 }
1939 }
1940 }
1941 }
1942 /* Try reg,reg */
1943 if(c==ADDI2P&&(p->typf&NU)==(UNSIGNED|CHAR)&&!ISFPOINTER(p->typf2)&&isreg(q2)/*&&p->q2.reg!=ra*/&&ISPREG(z)&&(ISPREG(q1)||p->q2.reg!=p->z.reg)){
1944 int base,idx,ind;struct obj *o;IC *free_idx,*dub=0;
1945 r=p->z.reg;idx=p->q2.reg;
1946 if(ISPREG(q1)) base=p->q1.reg; else base=r;
1947 if((p->q1.flags&VARADR)||(p->q1.flags&(KONST|DREFOBJ))==KONST)
1948 ind=0;
1949 else
1950 ind=1;
1951 o=0;free_base=free_idx=use=0;
1952 for(p2=p->next;p2;p2=p2->next){
1953 c2=p2->code;
1954 if(c2==CALL||c2==LABEL||(c2>=BEQ&&c2<=BRA)) break;
1955 if(c2==FREEREG&&p2->q1.reg==p->z.reg) free_base=p2;
1956 if(c2==FREEREG&&p2->q1.reg==p->q2.reg) free_idx=p2;
1957 if(c2!=FREEREG&&(p2->q1.flags&(REG|DREFOBJ))==REG&&p2->q1.reg==r) break;
1958 if(c2!=FREEREG&&(p2->q2.flags&(REG|DREFOBJ))==REG&&p2->q2.reg==r) break;
1959 if((p2->z.flags&(REG|DREFOBJ))==REG&&idx!=r){
1960 if(p2->z.reg==idx) break;
1961 if(reg_pair(p2->z.reg,&rp)){
1962 if(rp.r1==idx) break;
1963 if(rp.r2==idx) break;
1964 }
1965 }
1966
1967 if(c2!=CALL&&(c2<LABEL||c2>BRA)/*&&c2!=ADDRESS*/){
1968 if(!o&&(c2==ADD||c2==SUB||c2==AND||c2==OR||c2==XOR)&&/*(p2->typf&NQ)==CHAR&&*/!p2->q1.am&&!p2->z.am&&
1969 (p2->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&
1970 p2->q1.flags==p2->z.flags&&p2->q1.reg==r&&p2->z.reg==r){
1971 o=&p2->q1;use=p2;
1972 dub=p2;
1973 continue;
1974 }
1975 if(!p2->q1.am&&(p2->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->q1.reg==r){
1976 if(o||(ind&&(q1typ(p2)&NQ)!=CHAR)) break;
1977 if(ieee&&ISFLOAT(q1typ(p2))) break;
1978 o=&p2->q1;use=p2;
1979 }
1980 if(!p2->q2.am&&(p2->q2.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->q2.reg==r){
1981 if(o||(ind&&(q2typ(p2)&NQ)!=CHAR)) break;
1982 if(ieee&&ISFLOAT(q2typ(p2))) break;
1983 o=&p2->q2;use=p2;
1984 }
1985 if(!p2->z.am&&(p2->z.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&p2->z.reg==r){
1986 if(o||(ind&&(ztyp(p2)&NQ)!=CHAR)) break;
1987 if(ieee&&ISFLOAT(ztyp(p2))) break;
1988 o=&p2->z;use=p2;
1989 }
1990 }
1991
1992 if(c2==FREEREG||(p2->z.flags&(REG|DREFOBJ))==REG){
1993 int m;
1994 if(c2==FREEREG)
1995 m=p2->q1.reg;
1996 else
1997 m=p2->z.reg;
1998 if(m==r){
1999 if(o){
2000 o->am=am=mymalloc(sizeof(*am));
2001 am->idx=idx;
2002 if(ind){
2003 am->flags=GPR_IND;
2004 am->base=base;
2005 if(ISPREG(q1)){
2006 p->code=c=NOP;p->q1.flags=p->q2.flags=p->z.flags=0;
2007 }else{
2008 p->code=c=ASSIGN;p->q2.flags=0;
2009 p->typf=p->typf2;p->q2.val.vmax=sizetab[p->typf2&NQ];
2010 }
2011 }else{
2012 am->flags=ABS_IND;
2013 am->base=0;
2014 eval_const(&p->q1.val,MAXINT);
2015 am->offset=zm2l(vmax);
2016 if(p->q1.flags&VARADR)
2017 am->v=p->q1.v;
2018 else
2019 am->v=0;
2020 p->code=c=NOP;p->q1.flags=p->q2.flags=p->z.flags=0;
2021 }
2022 if(dub){
2023 dub->z=*o;
2024 dub->z.am=mymalloc(sizeof(*am));
2025 *dub->z.am=*o->am;
2026 }
2027 if(free_idx) move_IC(use,free_idx);
2028 if(free_base) move_IC(use,free_base);
2029 }
2030 break;
2031 }
2032 if(c2!=FREEREG&&m==base) break;
2033 continue;
2034 }
2035 }
2036 }
2037 }
2038}
2039
2040static void pr(FILE *f,struct IC *p)
2041{
2042 int r;
2043
2044 if(zstoreflag){
2045 int off;
2046 if(p->z.flags!=VAR||p->z.v!=&bankv) ierror(0);
2047 off=(int)zm2l(p->z.val.vmax);
2048 p->z=zstore;
2049 get_acc(f,p,INT);
2050 if(zstore.flags&DREFOBJ){
2051 if(!ISFPOINTER(zstore.dtyp)) ierror(0);
2052 zstore.flags&=~DREFOBJ;
2053 load_reg(f,LAST_PAIR,&zstore,POINTER);
2054 if(indirect(&zstore)){
2055 do_byte3(f,"lda",&zstore,FPOINTER);
2056 emit(f,"\ttay\n");
2057 }else
2058 do_byte3(f,"ldy",&zstore,FPOINTER);
2059 yval=NOVAL;
2060 }else{
2061 load_address(f,LAST_PAIR,&zstore,p->typf);
2062 r=bank(zstore.v);
2063 sety(f,r>=0?r:bankcnum);
2064 }
2065 emit(f,"\tldx\t#%d\n",off);
2066 emit(f,"\tlda\t#%d\n",cbank>=0?cbank:bankcnum);
2067 emit(f,"\tjsr\t%s__bankstore%d\n",idprefix,(int)zm2l(sizetab[p->typf&NQ]));
2068 yval=NOVAL;
2069 zstoreflag=0;
2070 }
2071
2072 for(r=1;r<=MAXR;r++){
2073 if(regs[r]&8)
2074 regs[r]&=~8;
2075 }
2076 for(r=FIRST_GPR;r<=LAST_GPR;r++){
2077 int ta=0;
2078 if(regs[r]&2){
2079 if(regs[ra]&&!pushedacc){
2080 emit(f,"\ttay\n");
2081 yval=NOVAL;
2082 ta=1;
2083 }
2084 emit(f,"\tpla\n");
2085 emit(f,"\tsta\t%s\n",mregnames[r]);
2086 regs[r]&=~2;
2087 }
2088 if(ta)
2089 emit(f,"\ttya\n");
2090 }
2091 if(pushedx){
2092 emit(f,"\tldx\t%s\n",mregnames[pushedx]);
2093 pushedx=0;
2094 }
2095
2096 reload_acc_opt(f,p->next);
2097
2098 storedacc=0;
2099 storedx=0;
2100}
2101
2102struct cmplist {struct cmplist *next;int from,to,mode;} *first_cmplist;
2103
2104static void add_cmplist(int from, int to, int mode)
2105{
2106 struct cmplist *new;
2107 new=mymalloc(sizeof(*new));
2108 new->next=first_cmplist;
2109 new->from=from;
2110 new->to=to;
2111 new->mode=mode;
2112 first_cmplist=new;
2113}
2114
2115static void incsp(FILE *f,long of)
2116{
2117 if(of==0) return;
2118 if(of==1||of==-1){
2119 static obj o;
2120 o.flags=REG;
2121 o.reg=sp;
2122 if(of==1)
2123 incmem(f,&o,INT,ADD,1);
2124 else
2125 incmem(f,&o,INT,SUB,1);
2126 }else if(of==256){
2127 emit(f,"\tinc\t%s+1\n",mregnames[sp]);
2128 }else if(of==-256){
2129 emit(f,"\tdec\t%s+1\n",mregnames[sp]);
2130 }else{
2131 long abs;
2132 if(of>0){
2133 abs=of;
2134 emit(f,"\tclc\n");
2135 }else{
2136 abs=-of;
2137 emit(f,"\tsec\n");
2138 }
2139 if(abs&255){
2140 emit(f,"\tlda\t%s\n",mregnames[sp]);
2141 if(of>0){
2142 emit(f,"\tadc\t#%ld\n",abs&255);
2143 }else{
2144 emit(f,"\tsbc\t#%ld\n",abs&255);
2145 }
2146 emit(f,"\tsta\t%s\n",mregnames[sp]);
2147 }
2148 if((abs&0xff00)==0){
2149 if(of>0){
2150 emit(f,"\tbcc\t%s%d\n",labprefix,++label);
2151 emit(f,"\tinc\t%s+1\n",mregnames[sp]);
2152 emit(f,"%s%d:\n",labprefix,label);
2153 }else{
2154 emit(f,"\tbcs\t%s%d\n",labprefix,++label);
2155 emit(f,"\tdec\t%s+1\n",mregnames[sp]);
2156 emit(f,"%s%d:\n",labprefix,label);
2157 }
2158 }else{
2159 emit(f,"\tlda\t%s+1\n",mregnames[sp]);
2160 if(of>0)
2161 emit(f,"\tadc\t#%ld\n",(abs>>8)&255);
2162 else
2163 emit(f,"\tsbc\t#%ld\n",(abs>>8)&255);
2164 emit(f,"\tsta\t%s+1\n",mregnames[sp]);
2165 }
2166 }
2167}
2168
2169/* generates the function entry code */
2170static void function_top(FILE *f,struct Var *v,long offset)
2171{
2172 int i,r,of;
2173 rsavesize=0;
2174 libsave=1;
2175 hasretval=0;
2176
2177 if(!optsize||(v->tattr&NOCOMPRESS)) emit(f,";vcprmin=10000\n");
2178 if(vlas) emit(f,"___fo\tset\t%ld\n",(long)argsize);
2179 r=0;
2180 for(i=FIRST_GPR;i<=LAST_GPR;i++){
2181 if((regused[i]&&(in_isr||!regscratch[i]))||(in_isr&&function_calls&&regscratch[i]&&!regsa[i])){
2182 if(i!=LAST_GPR-VOL_GPRS+1&&r==0) libsave=0;
2183 rsavesize++;
2184 r=1;
2185 }else{
2186 if(i==LAST_GPR-VOL_GPRS+1) libsave=0;
2187 r=0;
2188 }
2189 }
2190 rscnt=rsavesize;
2191 if(rscnt&&!SOFTSTACK){
2192 if(optspeed||rscnt<2)
2193 rsavesize=0;
2194 else if(!optsize&&rscnt<=5)
2195 rsavesize=0;
2196 }
2197
2198 if(!special_section(f,v)){emit(f,codename);ebank(f,sbank(v));if(f) section=CODE;}
2199 if(v->storage_class==EXTERN){
2200 if((v->flags&(INLINEFUNC|INLINEEXT))!=INLINEFUNC)
2201 emit(f,"\tglobal\t%s%s\n",idprefix,v->identifier);
2202 emit(f,"%s%s:\n",idprefix,v->identifier);
2203 }else
2204 emit(f,"%s%ld:\n",labprefix,zm2l(v->offset));
2205
2206 offset=localsize+argsize+rsavesize;
2207
2208 if(in_isr){
2209 emit(f,"\tpha\n");
2210 if(c02){
2211 emit(f,"\tphx\n");
2212 emit(f,"\tphy\n");
2213 }else{
2214 emit(f,"\ttxa\n");
2215 emit(f,"\tpha\n");
2216 emit(f,"\ttya\n");
2217 emit(f,"\tpha\n");
2218 }
2219 if(offset||function_calls){
2220 emit(f,"\tlda\t%s\n",mregnames[sp]);
2221 emit(f,"\tpha\n");
2222 emit(f,"\tlda\t%s+1\n",mregnames[sp]);
2223 emit(f,"\tpha\n");
2224 emit(f,"\tlda\t#<(___isrstack-%ld)\n",offset);
2225 emit(f,"\tsta\t%s\n",mregnames[sp]);
2226 emit(f,"\tlda\t#>(___isrstack-%ld)\n",offset);
2227 emit(f,"\tsta\t%s+1\n",mregnames[sp]);
2228 }
2229 }
2230
2231 if(MAINARGS&&v->storage_class==EXTERN&&!strcmp(v->identifier,"main")&&v->vtyp->exact->count>1)
2232 emit(f,"\tjsr\tinitmainargs\n");
2233
2234 yval=NOVAL;
2235 of=argsize+localsize;
2236
2237 if(rsavesize>0&&of+rsavesize>255){
2238 offset-=rsavesize;
2239 incsp(f,-rsavesize);
2240 of=0;
2241 }else{
2242 incsp(f,-offset);
2243 offset=0;
2244 }
2245
2246
2247 if(!libsave||rscnt!=rsavesize||optspeed||rscnt<=1||(rscnt<=3&&(!optsize)))
2248 libsave=0;
2249
2250 if(libsave){
2251 sety(f,of+rsavesize-1);
2252 if(0/*mask_opt*/)
2253 emit(f,"\tjsr\t%s__rsave.%d+%ld\n",idprefix,(1<<(rscnt-2)),(rscnt-2)*5);
2254 else
2255 emit(f,"\tjsr\t%s__rsave%ld\n",idprefix,rscnt);
2256 yval=of;
2257 }else{
2258 int last=0;
2259 for(i=FIRST_GPR;i<=LAST_GPR;i++){
2260 if((regused[i]&&(in_isr||!regscratch[i]))||(in_isr&&function_calls&&regscratch[i]&&!regsa[i])){
2261 if(rscnt!=rsavesize){
2262 if(ce02&&last==i-1){
2263 emit(f,"\tphw\t%s\n",mregnames[last]);
2264 last=0;
2265 }else{
2266 if(!ce02){
2267 emit(f,"\tlda\t%s\n",mregnames[i]);
2268 emit(f,"\tpha\n");
2269 }else
2270 last=i;
2271 }
2272 }else{
2273 sety(f,of++);
2274 emit(f,"\tlda\t%s\n",mregnames[i]);
2275 emit(f,"\tsta\t(%s),y\n",mregnames[sp]);
2276 }
2277 }
2278 }
2279 if(last){
2280 emit(f,"\tlda\t%s\n",mregnames[last]);
2281 emit(f,"\tpha\n");
2282 }
2283 }
2284
2285
2286
2287 incsp(f,-offset);
2288
2289 if(vlas){
2290 emit(f,"\tlda\t%s\n",mregnames[sp]);
2291 emit(f,"\tsta\t%s\n",mregnames[fp]);
2292 emit(f,"\tlda\t%s\n",mregnames[sp2]);
2293 emit(f,"\tsta\t%s\n",mregnames[fp2]);
2294 }
2295}
2296
2297/* generates the function exit code */
2298static void function_bottom(FILE *f,struct Var *v,long offset)
2299{
2300 int i,of,ar;
2301 struct cmplist *p;
2302 offset=localsize+argsize+rsavesize;
2303 of=argsize+localsize;
2304
2305 i=freturn(v->vtyp->next);
2306 if(hasretval&&(i==ra||i==rax)) ar=1; else ar=0;
2307
2308 if(rscnt!=rsavesize){
2309 if(ar&&!pushedacc){
2310 pushedacc=t4;
2311 emit(f,"\tsta\t%s\n",mregnames[pushedacc]);
2312 }
2313 for(i=LAST_GPR;i>=FIRST_GPR;i--){
2314 if((regused[i]&&(in_isr||!regscratch[i]))||(in_isr&&function_calls&&regscratch[i]&&!regsa[i])){
2315 emit(f,"\tpla\n");
2316 emit(f,"\tsta\t%s\n",mregnames[i]);
2317 }
2318 }
2319 }
2320 if(rsavesize>0&&of+rsavesize>255){
2321 if(of!=1&&ar&&!pushedacc){
2322 pushedacc=t4;
2323 emit(f,"\tsta\t%s\n",mregnames[pushedacc]);
2324 }
2325 incsp(f,of);
2326 offset-=of;
2327 of=0;
2328 }
2329 if(rsavesize>0){
2330 if(ar&&!pushedacc){
2331 pushedacc=t4;
2332 emit(f,"\tsta\t%s\n",mregnames[pushedacc]);
2333 }
2334 }
2335 if(rsavesize){
2336 if(libsave){
2337 sety(f,of+rsavesize-1);
2338 if(0/*mask_opt*/)
2339 emit(f,"\tjsr\t%s__rload.%d+%ld\n",idprefix,(1<<(rscnt-2)),(rscnt-2)*5);
2340 else
2341 emit(f,"\tjsr\t%s__rload%ld\n",idprefix,rscnt);
2342 yval=of;
2343 }else{
2344 for(i=FIRST_GPR;i<=LAST_GPR;i++){
2345 if((regused[i]&&(in_isr||!regscratch[i]))||(in_isr&&function_calls&&regscratch[i]&&!regsa[i])){
2346 sety(f,of++);
2347 emit(f,"\tlda\t(%s),y\n",mregnames[sp]);
2348 emit(f,"\tsta\t%s\n",mregnames[i]);
2349 }
2350 }
2351 }
2352 }
2353 if(in_isr){
2354 if(offset||function_calls){
2355 emit(f,"\tpla\n");
2356 emit(f,"\tsta\t%s+1\n",mregnames[sp]);
2357 emit(f,"\tpla\n");
2358 emit(f,"\tsta\t%s\n",mregnames[sp]);
2359 }
2360 }else if(offset==2&&!pushedacc){
2361 emit(f,"\tinc\t%s\n",mregnames[sp]);
2362 emit(f,"\tbeq\t%s%d\n",labprefix,++label);
2363 emit(f,"\tinc\t%s\n",mregnames[sp]);
2364 emit(f,"\tbeq\t%s%d\n",labprefix,++label);
2365 reload_acc(f);
2366 emit(f,ret);
2367 emit(f,"%s%d:\n",labprefix,label-1);
2368 emit(f,"\tinc\t%s\n",mregnames[sp]);
2369 emit(f,"%s%d:\n",labprefix,label);
2370 emit(f,"\tinc\t%s+1\n",mregnames[sp]);
2371 }else{
2372 if(offset!=0&&ar&&!pushedacc){
2373 pushedacc=t4;
2374 emit(f,"\tsta\t%s\n",mregnames[pushedacc]);
2375 }
2376 incsp(f,offset);
2377 }
2378
2379 reload_acc(f);
2380
2381 if(in_isr){
2382 if(c02){
2383 emit(f,"\tply\n");
2384 emit(f,"\tplx\n");
2385 }else{
2386 emit(f,"\tpla\n");
2387 emit(f,"\ttay\n");
2388 emit(f,"\tpla\n");
2389 emit(f,"\ttax\n");
2390 }
2391 emit(f,"\tpla\n");
2392 }
2393 emit(f,ret);
2394
2395 for(p=first_cmplist;p;){
2396 struct cmplist *m;
2397 emit(f,"%s%d:\n",labprefix,p->from);
2398 if(p->mode==JMPIND){
2399 /* indirect call */
2400 emit(f,"\tjmp\t(%s)\n",mregnames[p->to]);
2401 }else{
2402 pushedacc=p->mode;
2403 reload_acc(f);
2404 emit(f,"\t%s\t%s%d\n",jmpinst,labprefix,p->to);
2405 }
2406 m=p;
2407 p=p->next;
2408 free(m);
2409 }
2410 first_cmplist=0;
2411 pushedacc=0;
2412}
2413
2414/****************************************/
2415/* End of private data and functions. */
2416/****************************************/
2417
2418/* Does necessary initializations for the code-generator. Gets called */
2419/* once at the beginning and should return 0 in case of problems. */
2420int init_cg(void)
2421{
2422 int i;
2423 /* Initialize some values which cannot be statically initialized */
2424 /* because they are stored in the target's arithmetic. */
2425 maxalign=l2zm(1L);
2426 char_bit=l2zm(8L);
2427 stackalign=l2zm(1);
2428
2429 if(IEEE){
2430 ieee=1;
2431 msizetab[DOUBLE]=msizetab[LDOUBLE]=l2zm(8L);
2432 }
2433
2434
2435 mregnames[0]=regnames[0]="noreg";
2436 mregnames[REGDUMMY1]=mymalloc(MAXI+8);
2437 mregnames[REGDUMMY2]=mymalloc(MAXI+8);
2438 mregnames[REGDUMMY3]=mymalloc(MAXI+8);
2439
2440 for(i=FIRST_GPR;i<=LAST_GPR;i++){
2441 regnames[i]=mymalloc(10);
2442 sprintf(regnames[i],"r%d",i-FIRST_GPR);
2443 mregnames[i]=regnames[i];
2444 regsize[i]=l2zm(1L);
2445 regtype[i]=&ctyp;
2446 }
2447 for(i=FIRST_PAIR;i<=LAST_PAIR;i++){
2448 int sr=(i-FIRST_PAIR)*2+FIRST_GPR;
2449 regnames[i]=mymalloc(10);
2450 sprintf(regnames[i],"%s/%s",mregnames[sr],mregnames[sr+1]);
2451 mregnames[i]=regnames[sr];
2452 regsize[i]=l2zm(2L);
2453 regtype[i]=&ityp;
2454 }
2455 for(i=FIRST_BIG;i<=LAST_BIG;i++){
2456 regnames[i]=mymalloc(10);
2457 sprintf(regnames[i],"btmp%d",i-FIRST_BIG);
2458 mregnames[i]=regnames[i];
2459 regsize[i]=msizetab[FLOAT];
2460 regtype[i]=&ftyp;
2461 regsa[i]=0;
2462 regscratch[i]=1;
2463 }
2464 for(i=FIRST_BIGP;i<=LAST_BIGP;i++){
2465 int sr=(i-FIRST_BIGP)*2+FIRST_BIG;
2466 regnames[i]=mymalloc(20);
2467 sprintf(regnames[i],"%s/%s",mregnames[sr],mregnames[sr+1]);
2468 mregnames[i]=regnames[sr];
2469 regsize[i]=msizetab[LLONG];
2470 regtype[i]=&lltyp;
2471 regsa[i]=0;
2472 regscratch[i]=1;
2473 }
2474
2475 mregnames[ra] = regnames[ra] = "a";
2476 mregnames[rx] = regnames[rx] = "x";
2477 mregnames[ry] = regnames[ry] = "y";
2478 regsize[ra]=regsize[rx]=regsize[ry]=l2zm(1L);
2479 regtype[ra]=regtype[rx]=regtype[ry]=&ctyp;
2480 mregnames[sp]=regnames[sp] = "sp";
2481 mregnames[sp1]=regnames[sp1] = "sp";
2482 mregnames[sp2]=regnames[sp2] = "sp+1";
2483
2484 mregnames[rax]=regnames[rax] = "a/x";
2485 regsize[rax]=regsize[sp]=l2zm(2L);
2486 regtype[rax]=regtype[sp]=&ityp;
2487
2488 reg_prio[ra]=reg_prio[rax]=100;
2489 reg_prio[rx]=50;
2490
2491 /* Use multiple ccs. */
2492 multiple_ccs=0;
2493
2494 short_push=1;
2495
2496 static_cse=0;
2497
2498 dref_cse=1;
2499
2500 /*prefer_statics=1; TODO */
2501
2502
2503 if(optsize){
2504 clist_copy_stack=2;
2505 clist_copy_pointer=2;
2506 clist_copy_static=2;
2507 }else if(optspeed){
2508 clist_copy_stack=64;
2509 clist_copy_pointer=64;
2510 clist_copy_static=64;
2511 }else{
2512 clist_copy_stack=8;
2513 clist_copy_pointer=8;
2514 clist_copy_static=8;
2515 }
2516
2517 /* Initialize the min/max-settings. Note that the types of the */
2518 /* host system may be different from the target system and you may */
2519 /* only use the smallest maximum values ANSI guarantees if you */
2520 /* want to be portable. */
2521 /* That's the reason for the subtraction in t_min[INT]. Long could */
2522 /* be unable to represent -2147483648 on the host system. */
2523 t_min[CHAR]=l2zm(-128L);
2524 t_min[SHORT]=l2zm(-32768L);
2525 t_min[LONG]=zmsub(l2zm(-2147483647L),l2zm(1L));
2526 t_min[INT]=t_min(SHORT);
2527 t_min[LLONG]=zmlshift(l2zm(1L),l2zm(63L));
2528 t_min[MAXINT]=t_min(LLONG);
2529 t_max[CHAR]=ul2zum(127L);
2530 t_max[SHORT]=ul2zum(32767UL);
2531 t_max[LONG]=ul2zum(2147483647UL);
2532 t_max[INT]=t_max(SHORT);
2533 t_max[LLONG]=zumrshift(zumkompl(ul2zum(0UL)),ul2zum(1UL));
2534 t_max[MAXINT]=t_max(LLONG);
2535 tu_max[CHAR]=ul2zum(255UL);
2536 tu_max[SHORT]=ul2zum(65535UL);
2537 tu_max[LONG]=ul2zum(4294967295UL);
2538 tu_max[INT]=t_max(UNSIGNED|SHORT);
2539 tu_max[LLONG]=zumkompl(ul2zum(0UL));
2540 tu_max[MAXINT]=t_max(UNSIGNED|LLONG);
2541
2542 /* Reserve a few registers for use by the code-generator. */
2543 /* This is not optimal but simple. */
2544 regsa[ry]=regsa[sp]=regsa[sp1]=regsa[sp2]=REGSA_NEVER;
2545 regsa[t1]=regsa[t2]=regsa[t3]=regsa[t4]=REGSA_NEVER;
2546 regscratch[ra]=regscratch[rx]=regscratch[rax]=1;
2547 if(!GLOBACC)
2548 regsa[ra]=regsa[rx]=regsa[rax]=REGSA_TEMPS;
2549 regsa[rx]=0;
2550 regscratch[sp]=regscratch[sp1]=regscratch[sp2]=regscratch[ry]=0;
2551 regscratch[t1]=regscratch[t2]=regscratch[t3]=regscratch[t4]=1;
2552
2553 for(i=FIRST_GPR;i<=LAST_GPR-VOL_GPRS;i++){
2554 regscratch[i]=1;
2555 if(i&1)
2556 regscratch[FIRST_PAIR+(i-FIRST_GPR)/2]=1;
2557 }
2558
2559 target_macros=marray;
2560
2561 declare_builtin("__mulint8",CHAR,CHAR,FIRST_GPR,CHAR,FIRST_GPR+1,1,0);
2562 declare_builtin("__mulint16",INT,INT,FIRST_PAIR,INT,FIRST_PAIR+1,1,0);
2563 declare_builtin("__muluint16",UNSIGNED|INT,UNSIGNED|INT,FIRST_PAIR,UNSIGNED|INT,FIRST_PAIR+1,1,0);
2564 declare_builtin("__divuint16",UNSIGNED|INT,UNSIGNED|INT,FIRST_PAIR,UNSIGNED|INT,FIRST_PAIR+1,1,0);
2565 declare_builtin("__divint16",INT,INT,FIRST_PAIR,INT,FIRST_PAIR+1,1,0);
2566 declare_builtin("__modint16",INT,INT,FIRST_PAIR,INT,FIRST_PAIR+1,1,0);
2567 declare_builtin("__moduint16",UNSIGNED|INT,UNSIGNED|INT,FIRST_PAIR,UNSIGNED|INT,FIRST_PAIR+1,1,0);
2568 declare_builtin("__modint16wo",INT,INT,FIRST_PAIR,INT,FIRST_PAIR+1,1,0);
2569 declare_builtin("__divuint16wo",UNSIGNED|INT,UNSIGNED|INT,FIRST_PAIR,UNSIGNED|INT,FIRST_PAIR+1,1,0);
2570 declare_builtin("__divint16wo",INT,INT,FIRST_PAIR,INT,FIRST_PAIR+1,1,0);
2571 declare_builtin("__moduint16wo",UNSIGNED|INT,UNSIGNED|INT,FIRST_PAIR,UNSIGNED|INT,FIRST_PAIR+1,1,0);
2572 declare_builtin("__modint16wo",INT,INT,FIRST_PAIR,INT,FIRST_PAIR+1,1,0);
2573
2574 declare_builtin("__mulint32",LONG,LONG,FIRST_BIG+1,LONG,FIRST_BIG+2,1,0);
2575 declare_builtin("__muluint32",UNSIGNED|LONG,UNSIGNED|LONG,FIRST_BIG+1,UNSIGNED|LONG,FIRST_BIG+2,1,0);
2576 declare_builtin("__divint32",LONG,LONG,FIRST_BIG,LONG,FIRST_BIG+1,1,0);
2577 declare_builtin("__divuint32",UNSIGNED|LONG,UNSIGNED|LONG,FIRST_BIG,UNSIGNED|LONG,FIRST_BIG+1,1,0);
2578 declare_builtin("__modint32",LONG,LONG,FIRST_BIG,LONG,FIRST_BIG+1,1,0);
2579 declare_builtin("__moduint32",UNSIGNED|LONG,UNSIGNED|LONG,FIRST_BIG,UNSIGNED|LONG,FIRST_BIG+1,1,0);
2580 declare_builtin("__divint32wo",LONG,LONG,FIRST_BIG,LONG,FIRST_BIG+1,1,0);
2581 declare_builtin("__divuint32wo",UNSIGNED|LONG,UNSIGNED|LONG,FIRST_BIG,UNSIGNED|LONG,FIRST_BIG+1,1,0);
2582 declare_builtin("__modint32wo",LONG,LONG,FIRST_BIG,LONG,FIRST_BIG+1,1,0);
2583 declare_builtin("__moduint32wo",UNSIGNED|LONG,UNSIGNED|LONG,FIRST_BIG,UNSIGNED|LONG,FIRST_BIG+1,1,0);
2584
2585
2586
2587 declare_builtin("__mulint64",LLONG,LLONG,0,LLONG,0,1,0);
2588 declare_builtin("__addint64",LLONG,LLONG,0,LLONG,0,1,0);
2589 declare_builtin("__subint64",LLONG,LLONG,0,LLONG,0,1,0);
2590 declare_builtin("__andint64",LLONG,LLONG,0,LLONG,0,1,0);
2591 declare_builtin("__orint64",LLONG,LLONG,0,LLONG,0,1,0);
2592 declare_builtin("__eorint64",LLONG,LLONG,0,LLONG,0,1,0);
2593 declare_builtin("__negint64",LLONG,LLONG,0,0,0,1,0);
2594 declare_builtin("__lslint64",LLONG,LLONG,0,INT,0,1,0);
2595
2596 declare_builtin("__divint64",LLONG,LLONG,0,LLONG,0,1,0);
2597 declare_builtin("__divuint64",UNSIGNED|LLONG,UNSIGNED|LLONG,0,UNSIGNED|LLONG,0,1,0);
2598 declare_builtin("__modint64",LLONG,LLONG,0,LLONG,0,1,0);
2599 declare_builtin("__moduint64",UNSIGNED|LLONG,UNSIGNED|LLONG,0,UNSIGNED|LLONG,0,1,0);
2600 declare_builtin("__lsrint64",LLONG,LLONG,0,INT,0,1,0);
2601 declare_builtin("__lsruint64",UNSIGNED|LLONG,UNSIGNED|LLONG,0,INT,0,1,0);
2602 declare_builtin("__cmpsint64",INT,LLONG,0,LLONG,0,1,0);
2603 declare_builtin("__cmpuint64",INT,UNSIGNED|LLONG,0,UNSIGNED|LLONG,0,1,0);
2604
2605 declare_builtin("__sint32toflt32",FLOAT,LONG,OLDFP?0:FIRST_BIG,0,0,1,0);
2606 declare_builtin("__uint32toflt32",FLOAT,UNSIGNED|LONG,OLDFP?0:FIRST_BIG,0,0,1,0);
2607 declare_builtin("__flt32tosint32",LONG,FLOAT,OLDFP?0:FIRST_BIG,0,0,1,0);
2608 declare_builtin("__flt32touint32",UNSIGNED|LONG,FLOAT,OLDFP?0:FIRST_BIG,0,0,1,0);
2609 declare_builtin("__sint16toflt32",FLOAT,INT,FIRST_PAIR,0,0,1,0);
2610 declare_builtin("__uint16toflt32",FLOAT,UNSIGNED|INT,FIRST_PAIR,0,0,1,0);
2611 declare_builtin("__flt32tosint16",INT,FLOAT,OLDFP?0:FIRST_BIG,0,0,1,0);
2612 declare_builtin("__flt32touint16",UNSIGNED|INT,FLOAT,OLDFP?0:FIRST_BIG,0,0,1,0);
2613
2614 declare_builtin("__sint32toflt64",DOUBLE,LONG,OLDFP?0:FIRST_BIG,0,0,1,0);
2615 declare_builtin("__uint32toflt64",DOUBLE,UNSIGNED|LONG,OLDFP?0:FIRST_BIG,0,0,1,0);
2616 declare_builtin("__flt64tosint32",LONG,DOUBLE,OLDFP?0:FIRST_BIGP,0,0,1,0);
2617 declare_builtin("__flt64touint32",UNSIGNED|LONG,DOUBLE,OLDFP?0:FIRST_BIGP,0,0,1,0);
2618 declare_builtin("__sint16toflt64",DOUBLE,INT,FIRST_PAIR,0,0,1,0);
2619 declare_builtin("__uint16toflt64",DOUBLE,UNSIGNED|INT,FIRST_PAIR,0,0,1,0);
2620 declare_builtin("__flt64tosint16",INT,DOUBLE,OLDFP?0:FIRST_BIGP,0,0,1,0);
2621 declare_builtin("__flt64touint16",UNSIGNED|INT,DOUBLE,OLDFP?0:FIRST_BIGP,0,0,1,0);
2622
2623 declare_builtin("__flt64toflt32",FLOAT,DOUBLE,OLDFP?0:FIRST_BIGP,0,0,1,0);
2624 declare_builtin("__flt32toflt64",DOUBLE,FLOAT,OLDFP?0:FIRST_BIG,0,0,1,0);
2625
2626 declare_builtin("__addflt32",FLOAT,FLOAT,OLDFP?0:FIRST_BIG+1,FLOAT,OLDFP?0:FIRST_BIG,1,0);
2627 declare_builtin("__subflt32",FLOAT,FLOAT,OLDFP?0:FIRST_BIG+1,FLOAT,OLDFP?0:FIRST_BIG,1,0);
2628 declare_builtin("__mulflt32",FLOAT,FLOAT,OLDFP?0:FIRST_BIG+1,FLOAT,OLDFP?0:FIRST_BIG,1,0);
2629 declare_builtin("__divflt32",FLOAT,FLOAT,OLDFP?0:FIRST_BIG+1,FLOAT,OLDFP?0:FIRST_BIG,1,0);
2630 declare_builtin("__negflt32",FLOAT,FLOAT,OLDFP?0:FIRST_BIG,0,0,1,0);
2631 declare_builtin("__cmpsflt32",CHAR,FLOAT,OLDFP?0:FIRST_BIG+1,FLOAT,OLDFP?0:FIRST_BIG,1,0);
2632
2633#if 0
2634 for(i=1;i<MAXR;i++){
2635 printf("%02d %s scratch=%d ",i,regnames[i],regscratch[i]);
2636 if(reg_pair(i,&rp))
2637 printf("pair(%s,%s)",regnames[rp.r1],regnames[rp.r2]);
2638 printf("\n");
2639 }
2640#endif
2641
2642 if(NOPEEP) nopeep=1;
2643 if(CBMASCII) cbmascii=1;
2644 if(ATASCII) atascii=1;
2645 if(DIVBUG) divbug=1;
2646 if(M65IO) m65io=1;
2647 if(NOBANKING) manbank=1;
2648 jmpinst="jmp";
2649 if(C02||C02ALT){
2650 c02=1;zzero=1;
2651 jmpinst="bra";
2652 }
2653 if(CE02){
2654 c02=1;ce02=1;
2655 jmpinst="bra";
2656 }
2657 if(MEGA65){
2658 m65=1;c02=1;ce02=1;
2659 jmpinst="bra";
2660 }
2661
2662 for(i=0;i<=MAX_TYPE;i++){
2663 sizetab[i]=l2zm(msizetab[i]);
2664 align[i]=l2zm(malign[i]);
2665 }
2666
2667 bankv.storage_class=EXTERN;
2668 bankv.identifier="__bankv";
2669 bankv.vtyp=new_typ();
2670 bankv.vtyp->flags=CHAR;
2671
2672 bankcnum=COMMONBANK;
2673
2674 return 1;
2675}
2676
2677void init_db(FILE *f)
2678{
2679}
2680
2681int freturn(struct Typ *t)
2682/* Returns the register in which variables of type t are returned. */
2683/* If the value cannot be returned in a register returns 0. */
2684/* A pointer MUST be returned in a register. The code-generator */
2685/* has to simulate a pseudo register if necessary. */
2686{
2687 int typ=t->flags&NQ;
2688 if(ISSTRUCT(typ)||ISUNION(typ)||typ==VOID)
2689 return 0;
2690 if(OLDFP&&ISFLOAT(typ)) return FIRST_GPR;
2691 if(typ==LONG||typ==FLOAT||ISFPOINTER(typ)||(!ieee&&(typ==DOUBLE||typ==LDOUBLE)))
2692 return FIRST_BIG;
2693 if(typ==LLONG||(ieee&&(typ==DOUBLE||typ==LDOUBLE)))
2694 return FIRST_BIGP;
2695 if(zmleq(szof(t),l2zm(1L)))
2696 return ra;
2697 if(zmleq(szof(t),l2zm(2L)))
2698 return rax;
2699 else
2700 return 0;
2701}
2702
2703int reg_pair(int r,struct rpair *p)
2704/* Returns 0 if the register is no register pair. If r */
2705/* is a register pair non-zero will be returned and the */
2706/* structure pointed to p will be filled with the two */
2707/* elements. */
2708{
2709 if(r>=FIRST_PAIR&&r<=LAST_PAIR){
2710 p->r1=(r-FIRST_PAIR)*2+FIRST_GPR;
2711 p->r2=p->r1+1;
2712 return 1;
2713 }else if(r>=FIRST_BIGP&&r<=LAST_BIGP){
2714 p->r1=(r-FIRST_BIGP)*2+FIRST_BIG;
2715 p->r2=p->r1+1;
2716 return 1;
2717 }else if(r==rax){
2718 p->r1=ra;
2719 p->r2=rx;
2720 return 1;
2721 }else if(r==sp){
2722 p->r1=sp1;
2723 p->r2=sp2;
2724 return 1;
2725 }
2726 return 0;
2727}
2728
2729/* estimate the cost-saving if object o from IC p is placed in
2730 register r */
2731int cost_savings(struct IC *p,int r,struct obj *o)
2732{
2733 int c=p->code,co;
2734 if((o->flags&VAR)&&(o->v->tattr&ZPAGE)) return 0;
2735 if(indirect(o)) co=5; else co=2;
2736
2737 /*TODO: adapt this */
2738 if(o->flags&VKONST){
2739 if(o!=&p->q1||p->q2.flags!=0) return 0;
2740 if(r==ra||r==rax) return co;
2741 if(r==rx&&(c==ASSIGN||c==PUSH)) return co-1;
2742 return 0;
2743 }
2744
2745 if(ISIDX(r)){
2746 if(c==ADD||c==SUB||c==ADDI2P||c==SUBIFP||c==AND||c==OR||c==XOR){
2747 if(o==&p->q2&&c!=ADDI2P) return co-4;
2748 if(r==rx&&o==&p->q2&&((p->q1.flags&(VARADR|KONST|VKONST))==0||(p->q1.flags&DREFOBJ)))
2749 return co-4;
2750 if((c==ADD||c==SUB)&&o==&p->z&&(p->q2.flags&(KONST|DREFOBJ))==KONST){
2751 eval_const(&p->q2.val,q2typ(p));
2752 if(zmeqto(vmax,Z1)&&zumeqto(vumax,ZU1))
2753 return co+2;
2754 }
2755 }else if(c==ASSIGN||c==CONVERT){
2756 if(o==&p->q1&&indirect(&p->z)) return 1;
2757 if(o==&p->z&&indirect(&p->q1)) return 1;
2758 }else if(c==COMPARE){
2759 //if(o==&p->q1&&indirect(&p->q2)) return INT_MIN;
2760 //if(o==&p->q2&&indirect(&p->q1)) return INT_MIN;
2761 }else if(c==SETRETURN||c==GETRETURN||c==PUSH){
2762 }else if(c==TEST){
2763 }else
2764 return INT_MIN;
2765 }
2766
2767 if(c==ADDI2P&&o==&p->q1&&(p->typf&NU)==CHAR&&(r==rax))
2768 return INT_MIN;
2769
2770
2771 if(o->flags&DREFOBJ){
2772 if(isptr(r))
2773 return co+co+10;
2774 if(r==rax)
2775 return INT_MIN;
2776 }
2777 if(c==SETRETURN&&r==p->z.reg&&!(o->flags&DREFOBJ)) return co+2;
2778 if(c==GETRETURN&&r==p->q1.reg&&!(o->flags&DREFOBJ)) return co+2;
2779 if((c==ADD||c==SUB)&&o==&p->z&&p->q1.flags==p->z.flags&&p->q1.v==p->z.v&&(p->q2.flags&(KONST|DREFOBJ))==KONST){
2780 eval_const(&p->q2.val,q2typ(p));
2781 if(zmeqto(vmax,Z1)&&zumeqto(vumax,ZU1))
2782 return co+1;
2783 }
2784 if(r==ra)
2785 return co+2;
2786 if(ISIDX(r))
2787 return co+1;
2788 if(r==rax)
2789 return co+co+4;
2790 return co;
2791}
2792
2793int regok(int r,int t,int mode)
2794/* Returns 0 if register r cannot store variables of */
2795/* type t. If t==POINTER and mode!=0 then it returns */
2796/* non-zero only if the register can store a pointer */
2797/* and dereference a pointer to mode. */
2798{
2799 if(r==0)
2800 return 0;
2801 if(r==rax&&NORAX)
2802 return 0;
2803 if(r==rx&&NOX)
2804 return 0;
2805 t&=NQ;
2806 if(ISCHAR(t))
2807 if(r==ra||(ISIDX(r)&&(optflags&2))||(r>=FIRST_GPR&&r<=LAST_GPR))
2808 return 1;
2809 if(ISSHORT(t)){
2810 if(r==rax){
2811 if(t==POINTER&&mode<0)
2812 return 1;
2813 if(t!=POINTER)
2814 return 1;
2815 }
2816 if(r>=FIRST_PAIR&&r<=LAST_PAIR)
2817 return 1;
2818 }
2819 if(r>=FIRST_BIG&&r<=LAST_BIG){
2820 if(t==LONG||t==FLOAT||((t==DOUBLE||t==LDOUBLE)&&!ieee))
2821 return 1;
2822 if(t==FPOINTER)
2823 return 1;
2824 }
2825 if(r>=FIRST_BIGP&&r<=LAST_BIGP){
2826 if(t==LLONG||((t==DOUBLE||t==LDOUBLE)&&ieee))
2827 return 1;
2828 }
2829 return 0;
2830}
2831
2832int dangerous_IC(struct IC *p)
2833/* Returns zero if the IC p can be safely executed */
2834/* without danger of exceptions or similar things. */
2835/* vbcc may generate code in which non-dangerous ICs */
2836/* are sometimes executed although control-flow may */
2837/* never reach them (mainly when moving computations */
2838/* out of loops). */
2839/* Typical ICs that generate exceptions on some */
2840/* machines are: */
2841/* - accesses via pointers */
2842/* - division/modulo */
2843/* - overflow on signed integer/floats */
2844{
2845 int c=p->code;
2846 if((p->q1.flags&DREFOBJ)||(p->q2.flags&DREFOBJ)||(p->z.flags&DREFOBJ))
2847 return 1;
2848 if((c==DIV||c==MOD)&&!isconst(q2))
2849 return 1;
2850 return 0;
2851}
2852
2853int must_convert(int o,int t,int const_expr)
2854/* Returns zero if code for converting np to type t */
2855/* can be omitted. */
2856/* On the PowerPC cpu pointers and 32bit */
2857/* integers have the same representation and can use */
2858/* the same registers. */
2859{
2860 int op=o&NQ,tp=t&NQ;
2861
2862 if(op==tp) return 0;
2863 if(ISCHAR(op)&&ISCHAR(tp)) return 0;
2864 if(ISSHORT(op)&&ISSHORT(tp)) return 0;
2865 if(!ieee&&ISFLOAT(op)&&ISFLOAT(tp)) return 0;
2866 if(op==DOUBLE&&tp==LDOUBLE) return 0;
2867 if(op==LDOUBLE&&tp==DOUBLE) return 0;
2868
2869 return 1;
2870}
2871
2872void gen_ds(FILE *f,zmax size,struct Typ *t)
2873/* This function has to create <size> bytes of storage */
2874/* initialized with zero. */
2875{
2876 if(STDSYNTAX)
2877 emit(f,"\tspace\t%ld\n",zm2l(size));
2878 else
2879 emit(f,"\treserve\t%ld\n",zm2l(size));
2880 newobj=0;
2881}
2882
2883void gen_align(FILE *f,zmax align)
2884/* This function has to make sure the next data is */
2885/* aligned to multiples of <align> bytes. */
2886{
2887 if(zm2l(align)>1) emit(f,"\talign 1\n");
2888}
2889
2890void gen_var_head(FILE *f,struct Var *v)
2891/* This function has to create the head of a variable */
2892/* definition, i.e. the label and information for */
2893/* linkage etc. */
2894{
2895 int constflag,b=sbank(v);char *sec;
2896 if(v->clist) constflag=is_const(v->vtyp);
2897 if(v->storage_class==STATIC){
2898 if(ISFUNC(v->vtyp->flags)) return;
2899 if(v->tattr&ZPAGE)
2900 emit(f,"\tzpage\t%s%ld\n",labprefix,zm2l(v->offset));
2901 if(!special_section(f,v)){
2902 if(v->clist&&(!constflag||(g_flags[2]&USEDFLAG))){emit(f,dataname);ebank(f,b);if(f) section=DATA;}
2903 if(v->clist&&constflag&&!(g_flags[2]&USEDFLAG)){emit(f,rodataname);ebank(f,b);if(f) section=RODATA;}
2904 if(!v->clist){emit(f,bssname);ebank(f,b);if(f) section=BSS;}
2905 }
2906 gen_align(f,falign(v->vtyp));
2907 emit(f,"%s%ld:\n",labprefix,zm2l(v->offset));
2908 newobj=1;
2909 }
2910 if(v->storage_class==EXTERN){
2911 emit(f,"\t%s\t%s%s\n",(v->flags&NEEDS)?"needs":"global",idprefix,v->identifier);
2912 if(v->tattr&ZPAGE)
2913 emit(f,"\tzpage\t%s%s\n",idprefix,v->identifier);
2914 if(v->flags&(DEFINED|TENTATIVE)){
2915 if(!special_section(f,v)){
2916 if(v->clist&&(!constflag||(g_flags[2]&USEDFLAG))){emit(f,dataname);ebank(f,b);if(f) section=DATA;}
2917 if(v->clist&&constflag&&!(g_flags[2]&USEDFLAG)){emit(f,rodataname);ebank(f,b);if(f) section=RODATA;}
2918 if(!v->clist){emit(f,bssname);ebank(f,b);if(f) section=BSS;}
2919 }
2920
2921 gen_align(f,falign(v->vtyp));
2922 emit(f,"%s%s:\n",idprefix,v->identifier);
2923 newobj=1;
2924 }
2925 }
2926}
2927
2928void gen_dc(FILE *f,int t,struct const_list *p)
2929/* This function has to create static storage */
2930/* initialized with const-list p. */
2931{
2932 if(ISCHAR(t))
2933 emit(f,"\tbyte\t");
2934 else
2935 emit(f,"\tword\t");
2936 if(!p->tree){
2937 if(ISLONG(t)||ISFLOAT(t)){
2938 if(ieee&&ISFLOAT(t)){
2939 emit_ieee(f,&p->val,t&NQ);
2940 }else{
2941 eval_const(&p->val,t&NU);
2942 if(ISFLOAT(t)) cnv_fp();
2943 gval.vmax=zmand(vmax,l2zm(0xffffL));
2944 emitval(f,&gval,MAXINT);
2945 emit(f,",");
2946 gval.vmax=zmand(zmrshift(vmax,l2zm(16L)),l2zm(0xffffL));
2947 emitval(f,&gval,MAXINT);
2948 }
2949 }else{
2950 if(ISFPOINTER(t)){
2951 eval_const(&p->val,t&NU);
2952 emit(f,"%ld\n",(long)zm2l(vmax)&0xffff);
2953 emit(f,"\tbyte\t%d\n",(int)((zm2l(vmax)>>16)&0xff));
2954 }else
2955 emitval(f,&p->val,t&NU);
2956 }
2957 }else{
2958 emit_obj(f,&p->tree->o,t&NU);
2959 if(ISFPOINTER(t)){
2960 int b;
2961 if((p->tree->o.flags&(VAR|VARADR))!=(VAR|VARADR)) ierror(0);
2962 b=bank(p->tree->o.v);
2963 emit(f,"\n\tbyte\t%d",b>=0?b:bankcnum);
2964 }
2965 }
2966 emit(f,"\n");newobj=0;
2967}
2968
2969static int handle_m65(FILE *f,IC *p)
2970{
2971 int t=p->typf,c=p->code,noop2=0;
2972 if(c==MULT&&(ISSHORT(t)||ISCHAR(t))){
2973 get_acc(f,p,INT);
2974 load_acc(f,&p->q1,t);
2975 if(m65io){
2976 emit(f,"\tsta\t$d770\n");
2977 if(ISSHORT(t)) emit(f,"\tstx\t$d771\n");
2978 }else{
2979 emit(f,"\tldz\t#$70\n");
2980 emit(f,"\tstz\t___m65mathptr\n");
2981 emit(f,"\tstq\t[___m65mathptr]\n");
2982 }
2983 load_acc(f,&p->q2,t);
2984 if(m65io){
2985 emit(f,"\tsta\t$d774\n");
2986 if(ISSHORT(t)) emit(f,"\tstx\t$d775\n");
2987 }
2988 if(m65io){
2989 emit(f,"\tlda\t$d778\n");
2990 if(ISSHORT(t)) emit(f,"\tldx\t$d779\n");
2991 }else{
2992 emit(f,"\tldz\t#$74\n");
2993 emit(f,"\tstz\t___m65mathptr\n");
2994 emit(f,"\tstq\t[___m65mathptr]\n");
2995 emit(f,"\tldz\t#4\n");
2996 emit(f,"\tldq\t[___m65mathptr],z\n");
2997 emit(f,"\tldz\t#0\n");
2998 }
2999 yval=NOVAL;
3000 store_acc(f,&p->z,t);
3001 return 1;
3002 }
3003 if(ISLONG(t)&&LONGM65(c)){
3004 int mnoy;
3005
3006 if(c==ASSIGN&&isreg(q1)&&isreg(z)&&p->q1.reg==p->z.reg) return 1;
3007 if(c==GETRETURN&&isreg(z)&&p->z.reg==FIRST_BIG) return 1;
3008 if(c==SETRETURN&&isreg(q1)&&p->q1.reg==FIRST_BIG) return 1;
3009
3010 get_acc(f,p,INT);
3011
3012 if(c==LSHIFT||c==RSHIFT){
3013 int r,cnt=-1,mzzero;
3014
3015 if((p->q2.flags&(KONST|DREFOBJ))==KONST){
3016 eval_const(&p->q2.val,p->typf2);
3017 cnt=(int)(zm2l(vmax));
3018 cnt&=31;
3019 }
3020
3021 if(cnt==24||cnt==16||cnt==8||(cnt>=0&&(!optsize||cnt<=2))){
3022 r=0;
3023 }else{
3024 if(isreg(q2)&&p->q2.reg>=FIRST_GPR&&scratch(p,r,0)){
3025 r=p->q2.reg;
3026 if(reg_pair(r,&rp)) r=rp.r1;
3027 }else{
3028 /* TODO: improve for x or z */
3029 load_lobyte(f,&p->q2,p->typf2);
3030 r=t1;
3031 emit(f,"\tsta\t%s\n",mregnames[r]);
3032 }
3033 }
3034
3035 mzzero=zzero;
3036 zzero=0;
3037 if(cnt==24||(!optsize&&cnt>=24)){
3038 cnt-=24;
3039 if(c==LSHIFT){
3040 if(indirect(&p->q1)){
3041 load_lobyte(f,&p->q1,t);
3042 emit(f,"\ttaz\n");
3043 }else
3044 do_lobyte(f,"ldz",&p->q1,t);
3045 emit(f,"\tlda\t#0\n");
3046 emit(f,"\ttax\n");
3047 emit(f,"\ttay\n");
3048 yval=0;
3049 }else if(t&UNSIGNED){
3050 do_byte4(f,"lda",&p->q1,t);
3051 emit(f,"\tldx\t#0\n");
3052 emit(f,"\tldz\t#0\n");
3053 emit(f,"\tldy\t#0\n");
3054 yval=0;
3055 }else{
3056 emit(f,"\tldx\t#0\n");
3057 emit(f,"\tldz\t#0\n");
3058 emit(f,"\tldy\t#0\n");
3059 yval=0;
3060 do_byte4(f,"lda",&p->q1,t);
3061 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
3062 emit(f,"\tdex\n");
3063 if(yval==0)
3064 emit(f,"\tdey\n");
3065 emit(f,"\tdez\n");
3066 emit(f,"%s%d:\n",labprefix,label);
3067 if(yval!=0){
3068 emit(f,"\tphx\n");
3069 emit(f,"\tply\n");
3070 }
3071 }
3072 }else if(cnt==16||(!optsize&&cnt>=16)){
3073 cnt-=16;
3074 if(c==LSHIFT){
3075 if(indirect(&p->q1)){
3076 load_hibyte(f,&p->q1,t);
3077 emit(f,"\ttaz\n");
3078 load_lobyte(f,&p->q1,t);
3079 emit(f,"\ttay\n");
3080 }else{
3081 do_lobyte(f,"ldy",&p->q1,t);
3082 do_hibyte(f,"ldz",&p->q1,t);
3083 }
3084 emit(f,"\tlda\t#0\n");
3085 emit(f,"\ttax\n");
3086 }else if(t&UNSIGNED){
3087 if(indirect(&p->q1)){
3088 do_byte4(f,"lda",&p->q1,t);
3089 emit(f,"\ttax\n");
3090 do_byte3(f,"lda",&p->q1,t);
3091 }else{
3092 do_byte3(f,"lda",&p->q1,t);
3093 do_byte4(f,"ldx",&p->q1,t);
3094 }
3095 emit(f,"\tldy\t#0\n");
3096 emit(f,"\tldz\t#0\n");
3097 }else{
3098 emit(f,"\tldy\t#0\n");
3099 emit(f,"\tldz\t#0\n");
3100 yval=0;
3101 if(indirect(&p->q1)){
3102 do_byte4(f,"lda",&p->q1,t);
3103 emit(f,"\ttax\n");
3104 do_byte3(f,"lda",&p->q1,t);
3105 emit(f,"\tcpx\t#0\n");
3106 }else{
3107 do_byte3(f,"lda",&p->q1,t);
3108 do_byte4(f,"ldx",&p->q1,t);
3109 }
3110 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
3111 emit(f,"\tdez\n");
3112 if(yval==0)
3113 emit(f,"\tdey\n");
3114 emit(f,"%s%d:\n",labprefix,label);
3115 if(yval!=0){
3116 emit(f,"\tphz\n");
3117 emit(f,"\tply\n");
3118 }
3119 }
3120 }else if(cnt==8||(!optsize&&cnt>=8)){
3121 cnt-=8;
3122 if(c==LSHIFT){
3123 if(indirect(&p->q1)){
3124 do_byte3(f,"lda",&p->q1,t);
3125 emit(f,"\ttaz\n");
3126 load_lobyte(f,&p->q1,t);
3127 emit(f,"\ttax\n");
3128 load_hibyte(f,&p->q1,t);
3129 emit(f,"\ttay\n");
3130 }else{
3131 do_lobyte(f,"ldx",&p->q1,t);
3132 do_byte3(f,"ldz",&p->q1,t);
3133 do_hibyte(f,"ldy",&p->q1,t);
3134 }
3135 emit(f,"\tlda\t#0\n");
3136 }else if(t&UNSIGNED){
3137 emit(f,"\tldz\t#0\n");
3138 if(indirect(&p->q1)){
3139 do_byte4(f,"lda",&p->q1,t);
3140 emit(f,"\tpha\n");
3141 do_byte3(f,"lda",&p->q1,t);
3142 emit(f,"\ttax\n");
3143 do_hibyte(f,"lda",&p->q1,t);
3144 emit(f,"\tply\n");
3145 }else{
3146 do_hibyte(f,"lda",&p->q1,t);
3147 do_byte3(f,"ldx",&p->q1,t);
3148 do_byte4(f,"ldy",&p->q1,t);
3149 }
3150 }else{
3151 emit(f,"\tldz\t#0\n");
3152 if(indirect(&p->q1)){
3153 do_byte4(f,"lda",&p->q1,t);
3154 emit(f,"\tpha\n");
3155 do_byte3(f,"lda",&p->q1,t);
3156 emit(f,"\ttax\n");
3157 do_hibyte(f,"lda",&p->q1,t);
3158 emit(f,"\tply\n");
3159 }else{
3160 do_hibyte(f,"lda",&p->q1,t);
3161 do_byte3(f,"ldx",&p->q1,t);
3162 do_byte4(f,"ldy",&p->q1,t);
3163 }
3164 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
3165 emit(f,"\tdez\n");
3166 emit(f,"%s%d:\n",labprefix,label);
3167 }
3168 }else{
3169 mnoy=noy;
3170 ldq_offset(f,&p->q1);
3171 noy=2;
3172 emit(f,"\tldq\t");
3173 emit_obj(f,&p->q1,t);
3174 emit(f,"\n");
3175 noy=mnoy;
3176 }
3177 if(r){
3178 emit(f,"\tdec\t%s\n",mregnames[r]);
3179 emit(f,"\tbmi\t%s%d\n",labprefix,++label);
3180 emit(f,"%s%d:\n",labprefix,++label);
3181 emit(f,"\t%s\n",c==LSHIFT?"aslq":((t&UNSIGNED)?"lsrq":"asrq"));
3182 emit(f,"\tdec\t%s\n",mregnames[r]);
3183 emit(f,"\tbpl\t%s%d\n",labprefix,label);
3184 emit(f,"%s%d:\n",labprefix,label-1);
3185 }else{
3186 while(--cnt>=0)
3187 emit(f,"\t%s\n",c==LSHIFT?"aslq":((t&UNSIGNED)?"lsrq":"asrq"));
3188 }
3189 yval=NOVAL;
3190 mnoy=noy;
3191 noy=1;
3192 emit(f,"\tstq\t");
3193 emit_obj(f,&p->z,t);
3194 emit(f,"\n");
3195 noy=mnoy;
3196 emit(f,"\tldz\t#0\n");
3197 zzero=mzzero;
3198 return 1;
3199 }
3200
3201 if(c==PUSH){
3202 if(pushed){
3203 emit(f,"\tlda\t%s\n",mregnames[sp]);
3204 emit(f,"\tldx\t%s+1\n",mregnames[sp]);
3205 emit(f,"\tclc\n");
3206 emit(f,"\tadc\t#%d\n",pushed);
3207 emit(f,"\tbcc\t%s%d\n",labprefix,++label);
3208 emit(f,"\tinx\n");
3209 emit(f,"%s%d:\n",labprefix,label);
3210 emit(f,"\tsta\t%s\n",mregnames[t1]);
3211 emit(f,"\tstx\t%s\n",mregnames[t2]);
3212 }
3213 pushed+=4;
3214 }
3215 if((c==MULT||c==DIV)&&!m65io){
3216 emit(f,"\tlda\t#$70\n");
3217 emit(f,"\tsta\t___m65mathptr\n");
3218 }
3219 yval=NOVAL;
3220 noy=1;
3221 if((p->q1.flags&(KONST|DREFOBJ))==KONST){
3222 unsigned long v;
3223 eval_const(&p->q1.val,q1typ(p));
3224 v=zum2ul(vumax);
3225 emit(f,"\tlda\t#%d\n",(int)(v&255));v>>=8;
3226 emit(f,"\tldx\t#%d\n",(int)(v&255));v>>=8;
3227 emit(f,"\tldy\t#%d\n",(int)(v&255));v>>=8;
3228 emit(f,"\tldz\t#%d\n",(int)(v&255));
3229 }else if(c==GETRETURN){
3230 emit(f,"\tldq\t%s\n",mregnames[FIRST_BIG]);
3231 }else{
3232 noy=2;
3233 ldq_offset(f,&p->q1);
3234 emit(f,"\tldq\t");
3235 /*TODO: VARADR */
3236 if((p->q1.flags&VARADR)||(p->q1.flags&(KONST|DREFOBJ))==KONST){
3237 emit(f,"%s%d",labprefix,addfpconst(&p->q1,q1typ(p)));
3238 }else
3239 emit_obj(f,&p->q1,t);
3240 emit(f,"\n");
3241 noy=1;
3242 }
3243 if(c==ADD){
3244 if((p->q2.flags&(KONST|DREFOBJ))==KONST){
3245 eval_const(&p->q2.val,t);
3246 if(zmeqto(vmax,Z1)){noop2=1;emit(f,"\tinq\n");}
3247 else if(zmeqto(vmax,l2zm(2L))){noop2=1;emit(f,"\tinq\n\tinq\n");}
3248 else if(zmeqto(vmax,l2zm(3L))){noop2=1;emit(f,"\tinq\n\tinq\n\tinq\n");}
3249 else if(zmeqto(vmax,l2zm(4L))){noop2=1;emit(f,"\tinq\n\tinq\n\tinq\n\tinq\n");}
3250 }
3251 if(!noop2){
3252 emit(f,"\tclc\n");
3253 emit(f,"\tadcq\t");
3254 }
3255 }else if(c==SUB){
3256 if((p->q2.flags&(KONST|DREFOBJ))==KONST){
3257 eval_const(&p->q2.val,t);
3258 if(zmeqto(vmax,Z1)){noop2=1;emit(f,"\tdeq\n");}
3259 else if(zmeqto(vmax,l2zm(2L))){noop2=1;emit(f,"\tdeq\n\tdeq\n");}
3260 else if(zmeqto(vmax,l2zm(3L))){noop2=1;emit(f,"\tdeq\n\tdeq\n\tdeq\n");}
3261 else if(zmeqto(vmax,l2zm(4L))){noop2=1;emit(f,"\tdeq\n\tdeq\n\tdeq\n\tdeq\n");}
3262 }
3263 if(!noop2){
3264 emit(f,"\tsec\n");
3265 emit(f,"\tsbcq\t");
3266 }
3267 }else if(c==OR){
3268 emit(f,"\torq\t");
3269 }else if(c==AND){
3270 emit(f,"\tandq\t");
3271 }else if(c==XOR){
3272 emit(f,"\teorq\t");
3273 }else if(c==MULT||c==DIV){
3274 if(m65io){
3275 emit(f,"\tstq\t$d770\n");
3276 }else{
3277 emit(f,"\tstq\t[___m65mathptr]\n");
3278 emit(f,"\tlda\t#$74\n");
3279 emit(f,"\tsta\t___m65mathptr\n");
3280 }
3281 noy=2;
3282 ldq_offset(f,&p->q2);
3283 emit(f,"\tldq\t");
3284 }
3285 if(c!=ASSIGN&&c!=PUSH&&c!=GETRETURN&&c!=SETRETURN&&!noop2){
3286 if((p->q2.flags&VARADR)||(p->q2.flags&(KONST|DREFOBJ))==KONST){
3287 emit(f,"%s%d",labprefix,addfpconst(&p->q2,q2typ(p)));
3288 }else
3289 emit_obj(f,&p->q2,t);
3290 emit(f,"\n");
3291 }
3292 noy=1;
3293 if(c==MULT||c==DIV){
3294 if(m65io)
3295 emit(f,"\tstq\t$d774\n");
3296 else
3297 emit(f,"\tstq\t[___m65mathptr]\n");
3298 if(m65io){
3299 if(c==DIV){
3300 /* delay */
3301 emit(f,"\tlda\t$d76c\n");
3302 emit(f,"\tlda\t$d76c\n");
3303 emit(f,"\tlda\t$d76c\n");
3304 emit(f,"\tlda\t$d76c\n");
3305 emit(f,"\tldq\t$d76c\n");
3306 }else
3307 emit(f,"\tldq\t$d778\n");
3308 }else{
3309 if(c==DIV){
3310 emit(f,"\tlda\t#$6c\n");
3311 emit(f,"\tsta\t___m65mathptr\n");
3312 emit(f,"\tldz\t#0\n");
3313 emit(f,"\tlda\t[___m65mathptr],z\n"); /* delay for division */
3314 }else
3315 emit(f,"\tldz\t#4\n");
3316 emit(f,"\tldq\t[___m65mathptr],z\n");
3317 }
3318 }
3319 emit(f,"\tstq\t");
3320 if(c==PUSH)
3321 emit(f,"(%s)",pushed==4?mregnames[sp]:mregnames[t1]);
3322 else if(c==SETRETURN)
3323 emit(f,"%s",mregnames[FIRST_BIG]);
3324 else
3325 emit_obj(f,&p->z,t);
3326 emit(f,"\n");
3327 noy=0;
3328 if(zzero)
3329 emit(f,"\tldz\t#0\n");
3330 else
3331 ierror(0);
3332 return 1;
3333 }
3334 return 0;
3335}
3336
3337/* The main code-generation routine. */
3338/* f is the stream the code should be written to. */
3339/* p is a pointer to a doubly linked list of ICs */
3340/* containing the function body to generate code for. */
3341/* v is a pointer to the function. */
3342/* offset is the size of the stackframe the function */
3343/* needs for local variables. */
3344
3345void gen_code(FILE *f,struct IC *p,struct Var *v,zmax offset)
3346/* The main code-generation. */
3347{
3348 int c,t,i;
3349 struct IC *mi;
3350 FILE *rf=f;
3351 static char *dbgfile;
3352 static int dbgline;
3353
3354 if(vlas){
3355 fp=FPVLA_REG;
3356 if(!reg_pair(fp,&rp)) ierror(0);
3357 fp1=rp.r1;
3358 fp2=rp.r2;
3359 regused[fp]=regused[fp1]=regused[fp2]=1;
3360 }else{
3361 fp=sp;
3362 fp1=sp1;
3363 fp2=sp2;
3364 }
3365 argsize=0;
3366 localsize=offset;
3367 if(DEBUG&1) printf("gen_code()\n");
3368
3369 if(ce02) zzero=1; /* TODO: check what to do */
3370
3371 cbank=bank(v);
3372
3373 if(!v->fi) v->fi=new_fi();
3374 v->fi->flags|=ALL_REGS;
3375
3376 for(mi=p;mi;mi=mi->next)
3377 switch_IC(mi);
3378
3379 for(pass=0;pass<2;pass++){
3380
3381 if(DEBUG&1) printf("pass %d\n",pass);
3382
3383 if(pass==0){
3384 f=0;
3385 mi=clone_ic(p);
3386 }else
3387 f=rf;
3388
3389 for(c=1;c<=MAXR;c++) regs[c]=0; /*regsa[c];*/
3390 maxpushed=0;
3391
3392 /*FIXME*/
3393 if(v->tattr&INTERRUPT){
3394 ret="\trti\n";
3395 in_isr=1;
3396 }else{
3397 ret="\trts\n";
3398 in_isr=0;
3399 }
3400
3401 if(!nopeep) peephole(pass==0?p:mi);
3402
3403 function_top(f,v,localsize);
3404
3405 pushed=0;
3406
3407 yval=NOVAL;
3408
3409 dbgfile=0;
3410 dbgline=0;
3411
3412 for(p=pass==0?p:mi;p;pr(f,p),p=p->next){
3413
3414
3415
3416 if(DEBUG&1) pric2(stdout,p);
3417
3418 if(debug_info){
3419 if(p->file&&p->line){
3420 if(p->file!=dbgfile||p->line!=dbgline){
3421 dbgfile=p->file;
3422 dbgline=p->line;
3423 emit(f,"; %d \"%s\"\n",dbgline,dbgfile);
3424 }
3425 }
3426 }
3427
3428 c=p->code;t=p->typf;
3429
3430 if(c==NOP) {p->z.flags=0;continue;}
3431 if(c==ALLOCREG){
3432 regs[p->q1.reg]=1;
3433 if(reg_pair(p->q1.reg,&rp)){
3434 regs[rp.r1]=1;
3435 regs[rp.r2]=1;
3436 }
3437 continue;
3438 }
3439 if(c==FREEREG){
3440 regs[p->q1.reg]=0;
3441 if(reg_pair(p->q1.reg,&rp)){
3442 regs[rp.r1]=0;
3443 regs[rp.r2]=0;
3444 }
3445 continue;
3446 }
3447 if(c==LABEL) {emit(f,"%s%d:\n",labprefix,t);yval=NOVAL;continue;}
3448 if(c==BRA){
3449 yval=NOVAL;
3450 if(t==exit_label&&localsize+argsize+rsavesize+rscnt==0)
3451 emit(f,ret);
3452 else
3453 emit(f,"\t%s\t%s%d\n",jmpinst,labprefix,t);
3454 continue;
3455 }
3456 if(c>=BEQ&&c<BRA){
3457 yval=NOVAL;
3458 continue;
3459 }
3460
3461 if(c==MOVETOREG){
3462 p->code=c=ASSIGN;
3463 p->typf=t=regtype[p->z.reg]->flags;
3464 p->q2.val.vmax=sizetab[regtype[p->z.reg]->flags];
3465 }
3466 if(c==MOVEFROMREG){
3467 p->code=c=ASSIGN;
3468 p->typf=t=regtype[p->q1.reg]->flags;
3469 p->q2.val.vmax=sizetab[regtype[p->q1.reg]->flags];
3470 }
3471 if(c==CONVERT&&ISCHAR(t)&&ISCHAR(p->typf2)){
3472 p->code=c=ASSIGN;
3473 p->q2.val.vmax=sizetab[CHAR];
3474 }
3475 if(c==CONVERT&&msizetab[t&NQ]==3&&msizetab[p->typf2&NQ]==3){
3476 p->code=c=ASSIGN;
3477 p->q2.val.vmax=sizetab[SHORT];
3478 }
3479 if(c==CONVERT&&ISSHORT(t)&&ISSHORT(p->typf2)){
3480 p->code=c=ASSIGN;
3481 p->q2.val.vmax=sizetab[SHORT];
3482 }
3483 if(c==CONVERT&&ISLONG(t)&&ISLONG(p->typf2)){
3484 p->code=c=ASSIGN;
3485 p->q2.val.vmax=sizetab[LONG];
3486 }
3487 if(c==CONVERT&&ISLLONG(t)&&ISLLONG(p->typf2)){
3488 p->code=c=ASSIGN;
3489 p->q2.val.vmax=sizetab[LLONG];
3490 }
3491 if(c==CONVERT&&ISFLOAT(t)&&ISFLOAT(p->typf2)){
3492 p->code=c=ASSIGN;
3493 p->q2.val.vmax=sizetab[t&NQ];
3494 }
3495
3496
3497 /* switch commutative operands if suitable */
3498 if(c==ADD||c==MULT||c==AND||c==XOR||c==OR||(c==ADDI2P&&ISSHORT(t)&&!ISFPOINTER(p->typf2))){
3499 if((compare_objects(&p->q2,&p->z)&&!isacc(q1))||isacc(q2)){
3500 struct obj tmp;
3501 tmp=p->q1;
3502 p->q1=p->q2;
3503 p->q2=tmp;
3504 }
3505 }
3506
3507 if(c==COMPARE&&((p->q1.flags&(KONST|DREFOBJ))==KONST||ISRIDX(q2)||(isacc(q2)&&!ISRIDX(q1)))){
3508 obj tmp;IC *b;
3509 tmp=p->q1;
3510 p->q1=p->q2;
3511 p->q2=tmp;
3512 for(b=p->next;b;b=b->next){
3513 int bc;
3514 if(!b||b->code==LABEL) ierror(0);
3515 bc=b->code;
3516 if(bc==BGT){b->code=BLT;break;}
3517 if(bc==BGE){b->code=BLE;break;}
3518 if(bc==BLT){b->code=BGT;break;}
3519 if(bc==BLE){b->code=BGE;break;}
3520 if(bc==BNE||bc==BEQ) break;
3521 }
3522 }
3523
3524 c=p->code;
3525 if(c==SUBPFP) c=SUB;
3526 /*if(c==ADDI2P) c=ADD;*/
3527 /*if(c==SUBIFP) c=SUB;*/
3528
3529
3530 if(c==MINUS){
3531 if(isacc(q1)&&isacc(z)){
3532 emit(f,"\teor\t#255\n");
3533 if(c02&&ISCHAR(t)){
3534 emit(f,"\tina\n");
3535 }else{
3536 emit(f,"\tclc\n");
3537 emit(f,"\tadc\t#1\n");
3538 }
3539 if(!ISCHAR(t)){
3540 emit(f,"\tpha\n");
3541 emit(f,"\ttxa\n");
3542 emit(f,"\teor\t#255\n");
3543 emit(f,"\tadc\t#0\n");
3544 emit(f,"\ttax\n");
3545 emit(f,"\tpla\n");
3546 }
3547 continue;
3548 }
3549 p->code=c=SUB;
3550 p->q2=p->q1;
3551 p->q1.flags=KONST;
3552 p->q1.am=0;
3553 gval.vmax=Z0;
3554 eval_const(&gval,MAXINT);
3555 insert_const(&p->q1.val,t);
3556 }
3557
3558 preload(f,p);
3559
3560 if((c==ADD||c==SUB||c==ADDI2P||c==SUBIFP)&&compare_objects(&p->q1,&p->z)&&(!indirect(&p->q1)||(isreg(q1)&&ISIDX(p->q1.reg)))&&isconst(q2)&&!isacc(z)){
3561 long l;
3562 eval_const(&p->q2.val,q2typ(p));
3563 l=zm2l(vmax);
3564 if(c==ADDI2P/*&&(t2&NQ)==POINTER*/) {c=ADD;t=UNSIGNED|INT;}
3565 if(c==SUBIFP/*&&(t2&NQ)==POINTER*/) {c=SUB;t=UNSIGNED|INT;}
3566 if(c==SUB||c==SUBIFP) l=-l;
3567 /*TODO: allow larger types */
3568 if(l<3&&l>-3&&(t&NQ)<=INT){
3569 if(l<0){
3570 if(!c02||!isreg(q1)) get_acc(f,p,CHAR);
3571 incmem(f,&p->z,t,SUB,-l);
3572 }else
3573 incmem(f,&p->z,t,ADD,l);
3574 continue;
3575 }
3576 if(ISLONG(t)&&((m65&&labs(l)<3)||(optspeed&&l>0&&l<4)||(l>0&&l<2))){
3577 if(l<0){
3578 incmem(f,&p->z,t,SUB,-l);
3579 }else
3580 incmem(f,&p->z,t,ADD,l);
3581 continue;
3582 }
3583 }
3584
3585 if(m65&&handle_m65(f,p))
3586 continue;
3587
3588 if(c==CONVERT){
3589 int to=q1typ(p)&NU;
3590 t&=NU;
3591 if(ISCHAR(t)){
3592 if(!isacc(q1))
3593 get_acc(f,p,CHAR);
3594 load_lobyte(f,&p->q1,to);
3595 store_lobyte(f,&p->z,t);
3596 continue;
3597 }
3598 if(ISLONG(to)){
3599 if(!isacc(z))
3600 get_acc(f,p,CHAR);
3601 if(zm2l(sizetab[t&NQ])==3){
3602 do_byte3(f,"lda",&p->q1,to);
3603 do_byte3(f,"sta",&p->z,t);
3604 }
3605 if(zm2l(sizetab[t&NQ])>=2){
3606 if(isacc(z)&&!indirect(&p->q1)){
3607 do_hibyte(f,"ldx",&p->q1,to);
3608 }else{
3609 load_hibyte(f,&p->q1,to);
3610 store_hibyte(f,&p->z,t);
3611 }
3612 }
3613 load_lobyte(f,&p->q1,to);
3614 store_lobyte(f,&p->z,t);
3615 continue;
3616 }
3617 if(ISSHORT(to)){
3618 if((t&UNSIGNED)||ISFPOINTER(t))
3619 get_acc(f,p,CHAR);
3620 else
3621 get_acc(f,p,SHORT);
3622 load_lobyte(f,&p->q1,to);
3623 store_lobyte(f,&p->z,t);
3624 load_hibyte(f,&p->q1,to);
3625 store_hibyte(f,&p->z,t);
3626 if(ISFPOINTER(t)){
3627 int b=-1;
3628 if((p->q1.flags&(VARADR|DREFOBJ))==VARADR) b=bank(p->q1.v);
3629 emit(f,"\tlda\t#%d\n",b>=0?b:bankcnum);
3630 do_byte3(f,"sta",&p->z,t);
3631 continue;
3632 }
3633 if(to&UNSIGNED){
3634 if(zzero&&!indirect(&p->z)){
3635 do_byte3(f,"stz",&p->z,t);
3636 do_byte4(f,"stz",&p->z,t);
3637 }else{
3638 emit(f,"\tlda\t#0\n");
3639 do_byte3(f,"sta",&p->z,t);
3640 do_byte4(f,"sta",&p->z,t);
3641 }
3642 }else{
3643 emit(f,"\tldx\t#0\n");
3644 emit(f,"\tcmp\t#0\n");
3645 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
3646 emit(f,"\tdex\n");
3647 emit(f,"%s%d:\n",labprefix,label);
3648 if(indirect(&p->z)){
3649 emit(f,"\ttxa\n");
3650 do_byte3(f,"sta",&p->z,t);
3651 do_byte4(f,"sta",&p->z,t);
3652 }else{
3653 do_byte3(f,"stx",&p->z,t);
3654 do_byte4(f,"stx",&p->z,t);
3655 }
3656 }
3657 continue;
3658 }
3659 if(ISCHAR(to)){
3660 if(to&UNSIGNED){
3661 char *s;
3662 get_acc(f,p,CHAR);
3663 if(isreg(q1)&&p->q1.reg==rx&&!indirect(&p->z)){
3664 do_lobyte(f,"stx",&p->z,CHAR);
3665 }else{
3666 load_lobyte(f,&p->q1,to);
3667 store_lobyte(f,&p->z,t);
3668 }
3669 if(isacc(z)){
3670 emit(f,"\tldx\t#0\n");
3671 continue;
3672 }
3673 if(zzero&&!indirect(&p->z))
3674 s="stz";
3675 else{
3676 emit(f,"\tlda\t#0\n");
3677 s="sta";
3678 }
3679 do_hibyte(f,s,&p->z,t);
3680 if(ISLONG(t)){
3681 do_byte3(f,s,&p->z,t);
3682 do_byte4(f,s,&p->z,t);
3683 }
3684 }else{
3685 int l=++label;
3686 get_acc(f,p,SHORT);
3687 emit(f,"\tldx\t#0\n");
3688 if(isreg(q1)&&p->q1.reg==ra)
3689 emit(f,"\tcmp\t#0\n");
3690 else
3691 load_lobyte(f,&p->q1,to);
3692 emit(f,"\tbpl\t%s%d\n",labprefix,label);
3693 emit(f,"\tdex\n");
3694 emit(f,"%s%d:\n",labprefix,label);
3695 store_lobyte(f,&p->z,t);
3696 if(indirect(&p->z)&&(!isreg(z)||p->z.reg!=rax)){
3697 emit(f,"\ttxa\n");
3698 store_hibyte(f,&p->z,t);
3699 if(ISLONG(t)){
3700 do_byte3(f,"sta",&p->z,t);
3701 do_byte4(f,"sta",&p->z,t);
3702 }
3703 }else{
3704 if(!isreg(z)||p->z.reg!=rax){
3705 emit(f,"\tstx\t");
3706 emit_hibyte(f,&p->z,t);
3707 emit(f,"\n");
3708 }
3709 if(ISLONG(t)){
3710 do_byte3(f,"stx",&p->z,t);
3711 do_byte4(f,"stx",&p->z,t);
3712 }
3713 }
3714 }
3715 if(ISFPOINTER(t)){
3716 emit(f,"\tlda\t#%d\n",cbank>=0?cbank:bankcnum);
3717 do_byte3(f,"sta",&p->z,t);
3718 }
3719 continue;
3720 }
3721 if(ISFPOINTER(to)){
3722 get_acc(f,p,CHAR);
3723 if(zm2l(sizetab[t&NQ])>=3){
3724 do_byte3(f,"lda",&p->q1,to);
3725 do_byte3(f,"sta",&p->z,t);
3726 }
3727 if(zm2l(sizetab[t&NQ])>=2){
3728 load_hibyte(f,&p->q1,to);
3729 store_hibyte(f,&p->z,t);
3730 }
3731 load_lobyte(f,&p->q1,to);
3732 store_lobyte(f,&p->z,t);
3733
3734 continue;
3735 }
3736 pric2(stdout,p);
3737 ierror(0);
3738 }
3739
3740 if(c==KOMPLEMENT){
3741 get_acc(f,p,CHAR);
3742 if(ISCHAR(t)){
3743 load_acc(f,&p->q1,t);
3744 emit(f,"\teor\t#-1\n");
3745 store_acc(f,&p->z,t);
3746 }else{
3747 if(isacc(q1))
3748 emit(f,"\tpha\n");
3749 if(ISLONG(t)){
3750 do_byte4(f,"lda",&p->q1,t);
3751 emit(f,"\teor\t#-1\n");
3752 do_byte4(f,"sta",&p->z,t);
3753 do_byte3(f,"lda",&p->q1,t);
3754 emit(f,"\teor\t#-1\n");
3755 do_byte3(f,"sta",&p->z,t);
3756 }
3757 load_hibyte(f,&p->q1,t);
3758 emit(f,"\teor\t#-1\n");
3759 store_hibyte(f,&p->z,t);
3760 if(isacc(q1))
3761 emit(f,"\tpla\n");
3762 load_lobyte(f,&p->q1,t);
3763 emit(f,"\teor\t#-1\n");
3764 store_lobyte(f,&p->z,t);
3765 }
3766 continue;
3767 }
3768 if(c==SETRETURN){
3769 hasretval=1;
3770 t&=NQ;
3771 if(isreg(q1)&&p->q1.reg==p->z.reg) continue;
3772 if(t==LONG||t==LLONG||ISFLOAT(t)||ISFPOINTER(t)){
3773 long l=zm2l(p->q2.val.vmax);
3774 int zr=p->z.reg;
3775 //get_acc(f,p,t);
3776 if((optsize||l>4)&&!ISFPOINTER(t)){
3777 int ind=indirect(&p->q1);
3778 if(ind) load_address(f,LAST_PAIR,&p->q1,t);
3779 BSET(regused,t3);
3780 BSET(regused,t4);
3781 sety(f,l-1);
3782 emit(f,"%s%d:\n",labprefix,++label);
3783 if(ind)
3784 emit(f,"\tlda\t(%s),y\n",mregnames[LAST_PAIR]);
3785 else{
3786 emit(f,"\tlda\t");
3787 if(!ISFLOAT(t)&&(p->q1.flags&(KONST|DREFOBJ))==KONST){
3788 emit(f,"%s%d",labprefix,addfpconst(&p->q1,t));
3789 }else
3790 emit_obj(f,&p->q1,t);
3791 emit(f,",y\n");
3792 }
3793 emit(f,"\tsta\t%s,y\n",mregnames[zr]);
3794 emit(f,"\tdey\n");
3795 emit(f,"\tbpl\t%s%d\n",labprefix,label);
3796 yval=255;
3797 }else{
3798 if((p->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)){
3799 if(p->q1.reg==zr){
3800 int r=get_reg(f,p,POINTER);
3801 if(r==FIRST_PAIR||r==FIRST_PAIR+1)
3802 ierror(0);
3803 if(!reg_pair(r,&rp2)) ierror(0);
3804 emit(f,"\tlda\t%s\n",mregnames[zr]);
3805 emit(f,"\tsta\t%s\n",mregnames[rp2.r1]);
3806 emit(f,"\tlda\t%s+1\n",mregnames[zr]);
3807 emit(f,"\tsta\t%s\n",mregnames[rp2.r2]);
3808 p->q1.reg=r;
3809 }
3810 }
3811 load_lobyte(f,&p->q1,t);
3812 emit(f,"\tsta\t%s\n",mregnames[zr]);
3813 load_hibyte(f,&p->q1,t);
3814 emit(f,"\tsta\t%s+1\n",mregnames[zr]);
3815 do_byte3(f,"lda",&p->q1,t);
3816 emit(f,"\tsta\t%s+2\n",mregnames[zr]);
3817 if(!ISFPOINTER(t)){
3818 do_byte4(f,"lda",&p->q1,t);
3819 emit(f,"\tsta\t%s+3\n",mregnames[zr]);
3820 }
3821 /*TODO:regused OLDFP */
3822 regused[zr]=1;
3823 }
3824 continue;
3825 }
3826 //get_acc(f,p,t);
3827 load_acc(f,&p->q1,t);
3828 regused[ra]=1;
3829 regused[rx]=1;
3830 continue;
3831 }
3832 if(c==GETRETURN){
3833 t&=NQ;
3834 if(isreg(z)&&p->q1.reg==p->z.reg) continue;
3835 if(t==LONG||t==LLONG||ISFLOAT(t)||ISFPOINTER(t)){
3836 long l=zm2l(p->q2.val.vmax);
3837 int qr=p->q1.reg;
3838 if((optsize||l>4)&&!ISFPOINTER(t)){
3839 int ind=indirect(&p->z);
3840 if(ind) load_address(f,LAST_PAIR,&p->z,t);
3841 BSET(regused,t3);
3842 BSET(regused,t4);
3843 sety(f,l-1);
3844 emit(f,"%s%d:\n",labprefix,++label);
3845 emit(f,"\tlda\t%s,y\n",mregnames[qr]);
3846 if(ind)
3847 emit(f,"\tsta\t(%s),y\n",mregnames[LAST_PAIR]);
3848 else{
3849 emit(f,"\tsta\t");
3850 emit_obj(f,&p->z,t);
3851 emit(f,",y\n");
3852 }
3853 emit(f,"\tdey\n");
3854 emit(f,"\tbpl\t%s%d\n",labprefix,label);
3855 yval=255;
3856 }else{
3857 if((p->z.reg&(REG|DREFOBJ))==(REG|DREFOBJ)){
3858 if(p->z.reg==qr) ierror(0);
3859 }
3860 emit(f,"\tlda\t%s\n",mregnames[qr]);
3861 store_lobyte(f,&p->z,t);
3862 emit(f,"\tlda\t%s+1\n",mregnames[qr]);
3863 store_hibyte(f,&p->z,t);
3864 emit(f,"\tlda\t%s+2\n",mregnames[qr]);
3865 do_byte3(f,"sta",&p->z,t);
3866 if(!ISFPOINTER(t)){
3867 emit(f,"\tlda\t%s+3\n",mregnames[qr]);
3868 do_byte4(f,"sta",&p->z,t);
3869 }
3870 }
3871 continue;
3872 }
3873 if(p->q1.reg)
3874 store_acc(f,&p->z,t);
3875 continue;
3876 }
3877 if(c==CALL){
3878 int reg;
3879
3880 if(argsize<zm2l(p->q2.val.vmax)) argsize=zm2l(p->q2.val.vmax);
3881
3882 /*FIXME*/
3883#if 0
3884 if(stack_valid&&(p->q1.flags&(VAR|DREFOBJ))==VAR&&p->q1.v->fi&&(p->q1.v->fi->flags&ALL_STACK)){
3885 if(framesize+zum2ul(p->q1.v->fi->stack1)>stack)
3886 stack=framesize+zum2ul(p->q1.v->fi->stack1);
3887 }else
3888 stack_valid=0;
3889#endif
3890 if((p->q1.flags&(VAR|DREFOBJ))==VAR&&!strcmp("__va_start",p->q1.v->identifier)){
3891 long of=va_offset(v)+localsize+rsavesize+argsize;
3892 emit(f,"\tlda\t%s\n",mregnames[fp]);
3893 if(of){
3894 emit(f,"\tclc\n");
3895 if(of&255)
3896 emit(f,"\tadc\t#%d\n",(of&255));
3897 }
3898 emit(f,"\tldx\t%s+1\n",mregnames[fp]);
3899 if(of&0xff00){
3900 emit(f,"\tpha\n");
3901 emit(f,"\ttxa\n");
3902 emit(f,"\tadc\t#%d\n",(of>>8)&255);
3903 emit(f,"\ttax\n");
3904 emit(f,"\tpla\n");
3905 }else if(of){
3906 emit(f,"\tbcc\t%s%d\n",labprefix,++label);
3907 emit(f,"\tinx\n");
3908 emit(f,"%s%d:\n",labprefix,label);
3909 }
3910 continue;
3911 }
3912 if((p->q1.flags&(VAR|DREFOBJ))==VAR&&p->q1.v->fi&&p->q1.v->fi->inline_asm){
3913 emit(f,";startinline\n");
3914 emit_inline_asm(f,p->q1.v->fi->inline_asm);
3915 emit(f,";endinline\n");
3916 }else if(p->q1.flags&DREFOBJ){
3917 if(ISFPOINTER(p->q1.dtyp)){
3918 p->q1.flags&=~DREFOBJ;
3919 load_reg(f,LAST_PAIR,&p->q1,POINTER);
3920 if(indirect(&p->q1)){
3921 do_byte3(f,"lda",&p->q1,FPOINTER);
3922 emit(f,"\ttay\n");
3923 }else
3924 do_byte3(f,"ldy",&p->q1,FPOINTER);
3925 emit(f,"\tlda\t#%d\n",cbank>=0?cbank:bankcnum);
3926 emit(f,"\tjsr\t%s__bankjsr\n",idprefix);
3927 yval=NOVAL;
3928 }else{
3929 if(!(p->q1.flags&REG)) ierror(0);
3930 emit(f,"\tjsr\t%s%d\n",labprefix,++label);
3931 yval=NOVAL;
3932 add_cmplist(label,p->q1.reg,JMPIND);
3933 }
3934 }else{
3935 int tbank=-1;
3936 if(p->q1.flags&VAR) tbank=bank(p->q1.v);
3937 if(tbank!=cbank&&tbank>=0){
3938 if(cbank>=0){
3939 load_address(f,LAST_PAIR,&p->q1,t);
3940 sety(f,tbank);
3941 emit(f,"\tlda\t#%d\n",cbank);
3942 emit(f,"\tjsr\t%s__bankjsr\n",idprefix);
3943 yval=NOVAL;
3944 continue;
3945 }
3946 sety(f,tbank);
3947 emit(f,"\tjsr\t%s__bankswitch\n",idprefix);
3948 yval=NOVAL;
3949 }
3950 if((p->q1.flags&VAR)&&!strcmp(p->q1.v->identifier,"_fmemcpy"))
3951 emit(f,"\tlda\t#%d\n",cbank>=0?cbank:bankcnum);
3952 emit(f,"\tjsr\t");
3953 emit_obj(f,&p->q1,t);
3954 emit(f,"\n");
3955 }
3956 pushed-=zm2l(p->q2.val.vmax);
3957 if(!calc_regs(p,f!=0)&&v->fi) v->fi->flags&=~ALL_REGS;
3958 yval=NOVAL;
3959 continue;
3960 }
3961 if(c==ASSIGN||c==PUSH){
3962 if(t==0) ierror(0);
3963 if((p->q1.flags&(KONST|DREFOBJ))==KONST&&(t&NQ)==LLONG){
3964 int i;
3965 eval_const(&p->q1.val,t);
3966 for(i=0;i<8;i++){
3967 emit(f,"\tlda\t#%d\n",zm2l(vmax)&255);
3968 vmax=zmrshift(vmax,l2zm(8L));
3969 if(c==PUSH||(p->z.flags&DREFOBJ)){
3970 sety(f,i+((c==PUSH)?pushed:0));
3971 emit(f,"\tsta\t(%s),y\n",(c==PUSH)?mregnames[sp]:mregnames[p->z.reg]);
3972 }else{
3973 p->z.val.vmax=zmadd(p->z.val.vmax,l2zm((long)i));
3974 emit(f,"\tsta\t");
3975 emit_lobyte(f,&p->z,t);
3976 emit(f,"\n");
3977 p->z.val.vmax=zmsub(p->z.val.vmax,l2zm((long)i));
3978 }
3979 }
3980 if(c==PUSH) pushed+=8;
3981 continue;
3982 }
3983
3984 if(!zmleq(p->q2.val.vmax,l2zm(4L))){
3985 long len=zm2l(p->q2.val.vmax);
3986 int r1,r2,loops,looplab;
3987 if(len>32767) ierror(0);
3988 if(!NOBANKVARS){
3989 int bq=-1,bz=-1,s=-1;
3990 if((p->q1.flags&(VAR|DREFOBJ))==VAR) bq=bank(p->q1.v);
3991 if((p->z.flags&(VAR|DREFOBJ))==VAR) bz=bank(p->z.v);
3992 if(((p->q1.flags&DREFOBJ)&&ISFPOINTER(p->q1.dtyp))||
3993 ((p->z.flags&DREFOBJ)&&ISFPOINTER(p->z.dtyp))){
3994 far_copy(f,p);
3995 continue;
3996 }
3997 if(cbank<0){
3998 if(bq>=0&&bz>=0){
3999 if(bq!=bz){
4000 far_copy(f,p);
4001 continue;
4002 }
4003 s=bq;
4004 }else{
4005 if(bq>=0) s=bq;
4006 if(bz>=0) s=bz;
4007 }
4008 if(s>=0){
4009 sety(f,s);
4010 emit(f,"\tjsr\t%s__bankswitch\n",idprefix);
4011 yval=NOVAL;
4012 }
4013 }else{
4014 if((bq>=0&&bq!=cbank)||(bz>=0&&bz!=cbank)){
4015 far_copy(f,p);
4016 continue;
4017 }
4018 }
4019 }
4020 get_acc(f,p,CHAR);
4021 if((p->q1.flags&(DREFOBJ|KONST))==DREFOBJ){
4022 if(p->q1.flags&REG){
4023 r1=p->q1.reg;
4024 if(!reg_pair(r1,&rp)) ierror(0);
4025 if(len>128){
4026 emit(f,"\tlda\t%s\n",mregnames[rp.r1]);
4027 emit(f,"\tclc\n");
4028 if(len&128)
4029 emit(f,"\tadc\t#128\n");
4030 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
4031 if(len>255){
4032 emit(f,"\tlda\t%s\n",mregnames[rp.r2]);
4033 emit(f,"\tadc\t#%ld\n",(len>>8)&255);
4034 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
4035 }else{
4036 emit(f,"\tbcc\t%s%d\n",labprefix,++label);
4037 emit(f,"\tinc\t%s\n",mregnames[rp.r2]);
4038 emit(f,"%s%d:\n",labprefix,label);
4039 }
4040 }
4041 }else
4042 ierror(0);
4043 }else if(!indirect(&p->q1)&&len<=128&&(p->q1.flags&(DREFOBJ|KONST))!=KONST){
4044 r1=0;
4045 }else{
4046 Var *v=p->q1.v;
4047 /*if((p->q1.flags&(VARADR|VAR))!=VAR) ierror(0);*/
4048 /*printf("len=%ld %ld\n",len,len&0xff80);*/
4049 r1=get_reg(f,p,POINTER);
4050 if(len>128) p->q1.val.vmax=zmadd(p->q1.val.vmax,l2zm((len-1)&0xff80));
4051 load_address(f,r1,&p->q1,t);
4052 if(len>128) p->q1.val.vmax=zmsub(p->q1.val.vmax,l2zm((len-1)&0xff80));
4053 }
4054 if((p->z.flags&(DREFOBJ|KONST))==DREFOBJ){
4055 if(p->z.flags&REG){
4056 r2=p->z.reg;
4057 if(!reg_pair(r2,&rp)) ierror(0);
4058 if(len>128){
4059 emit(f,"\tlda\t%s\n",mregnames[rp.r1]);
4060 emit(f,"\tclc\n");
4061 if(len&128)
4062 emit(f,"\tadc\t#128\n");
4063 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
4064 if(len>255){
4065 emit(f,"\tlda\t%s\n",mregnames[rp.r2]);
4066 emit(f,"\tadc\t#%ld\n",(len>>8)&255);
4067 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
4068 }else{
4069 emit(f,"\tbcc\t%s%d\n",labprefix,++label);
4070 emit(f,"\tinc\t%s\n",mregnames[rp.r2]);
4071 emit(f,"%s%d:\n",labprefix,label);
4072 }
4073 }
4074 }else
4075 ierror(0);
4076 }else if(c==PUSH){
4077 if(len<=128&&pushed==0){
4078 r2=sp;
4079 }else{
4080 r2=get_reg(f,p,POINTER);
4081 if(!reg_pair(r2,&rp)) ierror(0);
4082 emit(f,"\tlda\t%s\n",mregnames[sp]);
4083 emit(f,"\tclc\n");
4084 if(((pushed+(len&128))&255)!=0)
4085 emit(f,"\tadc\t#%ld\n",(pushed+(len&128))&255);
4086 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
4087 emit(f,"\tlda\t%s\n",mregnames[sp2]);
4088 emit(f,"\tadc\t#%ld\n",((pushed+len)>>8)&255);
4089 emit(f,"\tsta\t%s\n",mregnames[rp.r2]);
4090 }
4091 }else if(!indirect(&p->z)&&len<=128){
4092 r2=0;
4093 }else{
4094 Var *v=p->z.v;
4095 r2=get_reg(f,p,POINTER);
4096 if(len>128) p->z.val.vmax=zmadd(p->z.val.vmax,l2zm((len-1)&0xff80));
4097 load_address(f,r2,&p->z,t);
4098 if(len>128) p->z.val.vmax=zmsub(p->z.val.vmax,l2zm((len-1)&0xff80));
4099 }
4100 if(len>128){
4101 get_acc(f,p,POINTER); /* get x */
4102 emit(f,"\tldx\t#%ld\n",(((len-128)>>7)+1)&255);
4103 }
4104 sety(f,(len-1)&127);
4105 if((optsize&&len>4)||len>8){
4106 emit(f,"%s%d:\n",labprefix,looplab=++label);
4107 if(optsize)
4108 loops=1;
4109 else{
4110 if((len&3)==0)
4111 loops=4;
4112 else if((len&1)==0)
4113 loops=2;
4114 else
4115 loops=1;
4116 }
4117 }else
4118 loops=len;
4119 if(r1&&!reg_pair(r1,&rp)) ierror(0);
4120 if(r2&&!reg_pair(r2,&rp2)) ierror(0);
4121 for(i=0;i<loops;i++){
4122 if(r1)
4123 emit(f,"\tlda\t(%s),y\n",mregnames[rp.r1]);
4124 else{
4125 emit(f,"\tlda\t");
4126 emit_obj(f,&p->q1,t);
4127 emit(f,",y\n");
4128 }
4129 if(r2)
4130 emit(f,"\tsta\t(%s),y\n",mregnames[rp2.r1]);
4131 else{
4132 emit(f,"\tsta\t");
4133 emit_obj(f,&p->z,t);
4134 emit(f,",y\n");
4135 }
4136 emit(f,"\tdey\n");
4137 }
4138 if(loops!=len){
4139 emit(f,"\tbpl\t%s%d\n",labprefix,label);
4140 }
4141 if(len>128){
4142 emit(f,"\tlda\t%s\n",mregnames[rp.r1]);
4143 emit(f,"\tsec\n");
4144 emit(f,"\tsbc\t#128\n");
4145 emit(f,"\tsta\t%s\n",mregnames[rp.r1]);
4146 emit(f,"\tbcs\t%s%d\n",labprefix,++label);
4147 emit(f,"\tdec\t%s\n",mregnames[rp.r2]);
4148 emit(f,"%s%d:\n",labprefix,label);
4149 emit(f,"\tlda\t%s\n",mregnames[rp2.r1]);
4150 emit(f,"\tsec\n");
4151 emit(f,"\tsbc\t#128\n");
4152 emit(f,"\tsta\t%s\n",mregnames[rp2.r1]);
4153 emit(f,"\tbcs\t%s%d\n",labprefix,++label);
4154 emit(f,"\tdec\t%s\n",mregnames[rp2.r2]);
4155 emit(f,"%s%d:\n",labprefix,label);
4156 emit(f,"\tldy\t#127\n");
4157 emit(f,"\tdex\n");
4158 emit(f,"\tbne\t%s%d\n",labprefix,looplab);
4159 }
4160 yval=NOVAL;
4161 if(c==PUSH)
4162 pushed+=zm2l(p->q2.val.vmax);
4163 continue;
4164 }
4165 if(c==PUSH){
4166 if(!scratch(p->next,ra,1))
4167 get_acc(f,p,CHAR);
4168 load_lobyte(f,&p->q1,t);
4169 if(zzero&&pushed==0){
4170 emit(f,"\tsta\t(%s)\n",mregnames[sp]);
4171 }else{
4172 sety(f,pushed);
4173 emit(f,"\tsta\t(%s),y\n",mregnames[sp]);
4174 }
4175 if(!zmleq(p->q2.val.vmax,Z1)){
4176 load_hibyte(f,&p->q1,t);
4177 sety(f,pushed+1);
4178 emit(f,"\tsta\t(%s),y\n",mregnames[sp]);
4179 }
4180 if(!zmleq(p->q2.val.vmax,l2zm(2L))){
4181 do_byte3(f,"lda",&p->q1,t);
4182 sety(f,pushed+2);
4183 emit(f,"\tsta\t(%s),y\n",mregnames[sp]);
4184 }
4185 if(!zmleq(p->q2.val.vmax,l2zm(3L))){
4186 do_byte4(f,"lda",&p->q1,t);
4187 sety(f,pushed+3);
4188 emit(f,"\tsta\t(%s),y\n",mregnames[sp]);
4189 }
4190
4191 pushed+=zm2l(p->q2.val.vmax);
4192 continue;
4193 }
4194 if(c==ASSIGN){
4195 int c2m;unsigned long v;
4196 if(isreg(q1)&&isreg(z)&&p->q1.reg==p->z.reg) continue;
4197 if(isacc(q1)){
4198 if(p->q1.reg==rax&&indirect(&p->z)) get_acc(f,p,CHAR);
4199 store_acc(f,&p->z,t);
4200 continue;
4201 }
4202 if(zzero&&!indirect(&p->z)&&(p->q1.flags&(DREFOBJ|KONST))==KONST){
4203 eval_const(&p->q1.val,t);
4204 if(ISFLOAT(t)){
4205 cnv_fp();
4206 v=zum2ul(zm2zum(vmax));
4207 }else
4208 v=zum2ul(vumax);
4209 c2m=1;
4210 }else
4211 c2m=0;
4212 if(!c2m||v!=0)
4213 get_acc(f,p,CHAR);
4214 if(0/*ISCHAR(t)*/){
4215 load_acc(f,&p->q1,t);
4216 store_acc(f,&p->z,t);
4217 }else{
4218 if(!zmleq(p->q2.val.vmax,l2zm(3L))){
4219 if(c2m&&(v&0xFF000000)==0){
4220 do_byte4(f,"stz",&p->z,t);
4221 }else{
4222 do_byte4(f,"lda",&p->q1,t);
4223 do_byte4(f,"sta",&p->z,t);
4224 }
4225 }
4226 if(!zmleq(p->q2.val.vmax,l2zm(2L))){
4227 if(c2m&&(v&0xFF0000)==0){
4228 do_byte3(f,"stz",&p->z,t);
4229 }else{
4230 do_byte3(f,"lda",&p->q1,t);
4231 do_byte3(f,"sta",&p->z,t);
4232 }
4233 }
4234 if(!zmleq(p->q2.val.vmax,l2zm(1L))){
4235 if(isreg(z)&&p->z.reg==rax&&!indirect(&p->q1)){
4236 do_hibyte(f,"ldx",&p->q1,t);
4237 }else if(c2m&&(v&0xFF00)==0){
4238 do_hibyte(f,"stz",&p->z,t);
4239 }else{
4240 load_hibyte(f,&p->q1,t);
4241 store_hibyte(f,&p->z,t);
4242 }
4243 }
4244 if(c2m&&(v&0xFF)==0){
4245 do_lobyte(f,"stz",&p->z,t);
4246 }else{
4247 if(isreg(q1)&&ISIDX(p->q1.reg)){
4248 store_reg(f,p->q1.reg,&p->z,CHAR);
4249 }else if(isreg(z)&&ISIDX(p->z.reg)){
4250 load_reg(f,p->z.reg,&p->q1,t);
4251 }else{
4252 load_lobyte(f,&p->q1,t);
4253 store_lobyte(f,&p->z,t);
4254 }
4255 }
4256 }
4257 }
4258 continue;
4259 }
4260 if(c==ADDRESS){
4261 long o=real_offset(&p->q1);
4262 get_acc(f,p,CHAR);
4263 emit(f,"\tlda\t%s\n",mregnames[fp1]);
4264 if(o){
4265 emit(f,"\tclc\n");
4266 if((o&255)!=0)
4267 emit(f,"\tadc\t#%ld\n",real_offset(&p->q1)&255);
4268 }
4269 if(isacc(z)){
4270 if(o==0) {emit(f,"\tldx\t%s\n",mregnames[fp2]);continue;}
4271 if(o==256){emit(f,"\tldx\t%s\n\tinx\n",mregnames[fp2]);continue;}
4272 if(o==512){emit(f,"\tldx\t%s\n\tinx\n\tinx\n",mregnames[fp2]);continue;}
4273 if(o<256){++label;emit(f,"\tldx\t%s\n\tbcc\t%s%d\n\tinx\n%s%d:\n",mregnames[fp2],labprefix,label,labprefix,label);continue;}
4274 if(o<512){++label;emit(f,"\tldx\t%s\n\tinx\n\tbcc\t%s%d\n\tinx\n%s%d:\n",mregnames[fp2],labprefix,label,labprefix,label);continue;}
4275 }
4276 store_lobyte(f,&p->z,t);
4277 if(isacc(z)) emit(f,"\tpha\n");
4278 emit(f,"\tlda\t%s\n",mregnames[fp2]);
4279 if(o!=0)
4280 emit(f,"\tadc\t#%ld\n",real_offset(&p->q1)>>8&255);
4281 store_hibyte(f,&p->z,t);
4282 if(isacc(z)) emit(f,"\tpla\n");
4283 continue;
4284 }
4285
4286 if(c==COMPARE||c==TEST){
4287 IC *branch=p->next;
4288 int pacc=0,bc,bout;
4289 if(ISPOINTER(t)) t|=UNSIGNED;
4290 while(branch){
4291 if(branch->code>=BEQ&&branch->code<BRA)
4292 break;
4293 if(branch->code!=FREEREG&&branch->code!=ALLOCREG&&branch->code!=NOP)
4294 ierror(0);
4295 branch=branch->next;
4296 }
4297 bc=branch->code;
4298 bout=branch->typf;
4299 if(c==TEST){
4300 p->q2.flags=KONST;
4301 gval.vmax=Z0;
4302 eval_const(&gval,MAXINT);
4303 insert_const(&p->q2.val,t);
4304 }
4305 if((t&NU)==(UNSIGNED|CHAR)&&(bc==BLE||bc==BGT)&&(p->q2.flags&(DREFOBJ|KONST))==KONST){
4306 eval_const(&p->q2.val,t);
4307 if(!zmeqto(vmax,l2zm(255L))){
4308 vmax=zmadd(vmax,Z1);
4309 gval.vmax=vmax;
4310 eval_const(&gval,t);
4311 insert_const(&p->q2.val,t);
4312 if(bc==BLE) bc=BLT; else bc=BGE;
4313 branch->code=bc;
4314 }
4315 }
4316 if(((t&NQ)==SHORT||(t&NQ)==INT||(t&NQ)==LONG)&&(bc==BNE||bc==BEQ)&&isconst(q2)&&!isacc(q1)){
4317 eval_const(&p->q2.val,t);
4318 if(zmeqto(vmax,Z0)&&zumeqto(vumax,ZU0)){
4319 if(pacc=cmp_get_acc(f,p,branch))
4320 bout=++label;
4321 load_lobyte(f,&p->q1,t);
4322 do_hibyte(f,"ora",&p->q1,t);
4323 if((t&NQ)==LONG){
4324 do_byte3(f,"ora",&p->q1,t);
4325 do_byte4(f,"ora",&p->q1,t);
4326 }
4327 emit(f,"\t%s\t%s%d\n",(bc==BNE)?"bne":"beq",labprefix,bout);
4328 if(pacc){
4329 reload_acc(f);
4330 add_cmplist(bout,branch->typf,pacc);
4331 }
4332 continue;
4333 }
4334 }
4335 if(ieee&&ISFLOAT(t)){
4336 if(!ieee) ierror(0);
4337 t&=NQ;
4338 if(regs[LAST_PAIR]) ierror(0);
4339 regs[LAST_PAIR]=1;
4340 if(regs[ra]||regs[rax])
4341 ierror(0);
4342 load_address(f,LAST_PAIR,&p->q2,t);
4343 BSET(regused,t3);
4344 BSET(regused,t4);
4345 emit(f,"\tjsr\t%s__fload%c\n",idprefix,(t==FLOAT?'s':'d'));
4346 yval=NOVAL;
4347 load_address(f,LAST_PAIR,&p->q1,t);
4348 emit(f,"\tjsr\t%s__fcmp%c\n",idprefix,(t==FLOAT?'s':'d'));
4349 yval=NOVAL;
4350 regs[LAST_PAIR]=0;
4351 if(bc==BLT||bc==BLE)
4352 emit(f,"\tbmi\t%s%d\n",labprefix,bout);
4353 else if(bc==BGT|bc==BGE)
4354 emit(f,"\tbvs\t%s%d\n",labprefix,bout);
4355 if(bc==BEQ||bc==BLE||bc==BGE)
4356 emit(f,"\tbeq\t%s%d\n",labprefix,bout);
4357 if(bc==BNE)
4358 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4359 continue;
4360 }
4361 if(ISCHAR(t)){
4362 char *s=0;
4363 if(isreg(q1)&&ISIDX(p->q1.reg)&&!indirect(&p->q2)&&(bc==BEQ||bc==BNE||(t&UNSIGNED))){
4364 static char buf[4]="cpr";
4365 s=buf;s[2]=mregnames[p->q1.reg][0];
4366 }else{
4367 if(pacc=cmp_get_acc(f,p,branch))
4368 bout=++label;
4369 load_acc(f,&p->q1,t);
4370 if(bc==BEQ||bc==BNE||(t&UNSIGNED)){
4371 s="cmp";
4372 }else{
4373 if(bc==BLT||bc==BGE)
4374 emit(f,"\tsec\n");
4375 else
4376 emit(f,"\tclc\n");
4377 s="sbc";
4378 }
4379 }
4380 if(c==TEST)
4381 emit(f,"\t%s\t#0\n",s);
4382 else
4383 do_lobyte(f,s,&p->q2,t);
4384 if(bc==BEQ)
4385 emit(f,"\tbeq\t%s%d\n",labprefix,bout);
4386 else if(bc==BNE)
4387 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4388 else if(t&UNSIGNED){
4389 if(bc==BLT)
4390 emit(f,"\tbcc\t%s%d\n",labprefix,bout);
4391 else if(bc==BGE)
4392 emit(f,"\tbcs\t%s%d\n",labprefix,bout);
4393 else if(bc==BLE){
4394 emit(f,"\tbcc\t%s%d\n",labprefix,bout);
4395 emit(f,"\tbeq\t%s%d\n",labprefix,bout);
4396 }else if(bc==BGT){
4397 emit(f,";\n\tbeq\t%s%d\n",labprefix,++label);
4398 emit(f,"\tbcs\t%s%d\n",labprefix,bout);
4399 emit(f,"%s%d:\n",labprefix,label);
4400 }else
4401 ierror(0);
4402 }else{
4403 emit(f,"\tbvc\t%s%d\n",labprefix,++label);
4404 emit(f,"\teor\t#128\n");
4405 emit(f,"%s%d:\n",labprefix,label);
4406 if(bc==BLT||bc==BLE)
4407 emit(f,"\tbmi\t%s%d\n",labprefix,bout);
4408 else
4409 emit(f,"\tbpl\t%s%d\n",labprefix,bout);
4410 }
4411 if(pacc){
4412 reload_acc(f);
4413 add_cmplist(bout,branch->typf,pacc);
4414 }
4415 continue;
4416 }else if(bc==BEQ||bc==BNE||(t&UNSIGNED)||ISFPOINTER(t)){
4417 int in=0;
4418 if(pacc=cmp_get_acc(f,p,branch))
4419 bout=++label;
4420 if(ISLONG(t)){
4421 do_byte4(f,"lda",&p->q1,t);
4422 if(c==TEST)
4423 emit(f,"\tcmp\t#0\n");
4424 else
4425 do_byte4(f,"cmp",&p->q2,t);
4426 if(bc==BEQ)
4427 emit(f,"\tbne\t%s%d\n",labprefix,in=++label);
4428 else if(bc==BNE)
4429 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4430 else if(bc==BLT||bc==BLE){
4431 emit(f,"\tbcc\t%s%d\n",labprefix,bout);
4432 emit(f,"\tbne\t%s%d\n",labprefix,in=++label);
4433 }else if(bc==BGE||bc==BGT){
4434 emit(f,"\tbcc\t%s%d\n",labprefix,in=++label);
4435 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4436 }else
4437 ierror(0);
4438 }
4439 if(ISLONG(t)||ISFPOINTER(t)){
4440 do_byte3(f,"lda",&p->q1,t);
4441 if(c==TEST)
4442 emit(f,"\tcmp\t#0\n");
4443 else
4444 do_byte3(f,"cmp",&p->q2,t);
4445 if(bc==BEQ)
4446 emit(f,"\tbne\t%s%d\n",labprefix,in?in:(in=++label));
4447 else if(bc==BNE)
4448 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4449 else if(bc==BLT||bc==BLE){
4450 emit(f,"\tbcc\t%s%d\n",labprefix,bout);
4451 emit(f,"\tbne\t%s%d\n",labprefix,in?in:(in=++label));
4452 }else if(bc==BGE||bc==BGT){
4453 emit(f,"\tbcc\t%s%d\n",labprefix,in?in:(in=++label));
4454 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4455 }else
4456 ierror(0);
4457 }
4458 if(isacc(q1)){
4459 if(!indirect(&p->q2)){
4460 do_hibyte(f,"cpx",&p->q2,t);
4461 }else{
4462 int r=get_reg(f,p,CHAR);
4463 emit(f,"\tpha\n");
4464 load_hibyte(f,&p->q2,t);
4465 emit(f,"\tsta\t%s\n",mregnames[r]);
4466 emit(f,"\tpla\n");
4467 emit(f,"\tcpx\t%s\n",mregnames[r]);
4468 }
4469 }else{
4470 load_hibyte(f,&p->q1,t);
4471 if(c==TEST)
4472 emit(f,"\tcmp\t#0\n");
4473 else
4474 do_hibyte(f,"cmp",&p->q2,t);
4475 }
4476 if(bc==BEQ)
4477 emit(f,"\tbne\t%s%d\n",labprefix,in?in:(in=++label));
4478 else if(bc==BNE)
4479 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4480 else if(bc==BLT||bc==BLE){
4481 emit(f,"\tbcc\t%s%d\n",labprefix,bout);
4482 emit(f,"\tbne\t%s%d\n",labprefix,in?in:(in=++label));
4483 }else if(bc==BGE||bc==BGT){
4484 emit(f,"\tbcc\t%s%d\n",labprefix,in?in:(in=++label));
4485 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4486 }else
4487 ierror(0);
4488 load_lobyte(f,&p->q1,t);
4489 if(c==TEST)
4490 emit(f,"\tcmp\t#0\n");
4491 else
4492 do_lobyte(f,"cmp",&p->q2,t);
4493 if(bc==BEQ)
4494 emit(f,"\tbeq\t%s%d\n",labprefix,bout);
4495 else if(bc==BNE)
4496 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4497 else if(bc==BLT)
4498 emit(f,"\tbcc\t%s%d\n",labprefix,bout);
4499 else if(bc==BGE)
4500 emit(f,"\tbcs\t%s%d\n",labprefix,bout);
4501 else if(bc==BLE){
4502 emit(f,"\tbcc\t%s%d\n",labprefix,bout);
4503 emit(f,"\tbeq\t%s%d\n",labprefix,bout);
4504 }else if(bc==BGT){
4505 emit(f,"\tbcc\t%s%d\n",labprefix,in);
4506 emit(f,"\tbne\t%s%d\n",labprefix,bout);
4507 }else
4508 ierror(0);
4509 if(in)
4510 emit(f,"%s%d:\n",labprefix,in);
4511 if(pacc){
4512 reload_acc(f);
4513 add_cmplist(bout,branch->typf,pacc);
4514 }
4515 continue;
4516 }else{
4517 if(bc==BGT||bc==BLE){
4518 obj o;
4519 if(isacc(q1)){
4520 int r;
4521 if(pacc=cmp_get_acc(f,p,branch))
4522 bout=++label;
4523 r=get_reg(f,p,CHAR);
4524 emit(f,"\tsta\t%s\n",mregnames[r]);
4525 load_lobyte(f,&p->q2,t);
4526 emit(f,"\tcmp\t%s\n",mregnames[r]);
4527 emit(f,"\tstx\t%s\n",mregnames[r]);
4528 load_hibyte(f,&p->q2,t);
4529 emit(f,"\tsbc\t%s\n",mregnames[r]);
4530 emit(f,"\tbvc\t%s%d\n",labprefix,++label);
4531 emit(f,"\teor\t#128\n");
4532 emit(f,"%s%d:\n",labprefix,label);
4533 if(bc==BGT)
4534 emit(f,"\tbmi\t%s%d\n",labprefix,bout);
4535 else
4536 emit(f,"\tbpl\t%s%d\n",labprefix,bout);
4537 if(pacc){
4538 reload_acc(f);
4539 add_cmplist(bout,branch->typf,pacc);
4540 }
4541 continue;
4542 }else{
4543 o=p->q1;p->q1=p->q2;p->q2=o;
4544 if(bc==BGT) bc=BLT; else bc=BGE;
4545 }
4546 }
4547 if(pacc=cmp_get_acc(f,p,branch))
4548 bout=++label;
4549 if(ISLONG(t)){
4550 load_lobyte(f,&p->q1,t);
4551 do_lobyte(f,"cmp",&p->q2,t);
4552 load_hibyte(f,&p->q1,t);
4553 do_hibyte(f,"sbc",&p->q2,t);
4554 do_byte3(f,"lda",&p->q1,t);
4555 do_byte3(f,"sbc",&p->q2,t);
4556 do_byte4(f,"lda",&p->q1,t);
4557 do_byte4(f,"sbc",&p->q2,t);
4558 }else{
4559 load_lobyte(f,&p->q1,t);
4560 do_lobyte(f,"cmp",&p->q2,t);
4561 load_hibyte(f,&p->q1,t);
4562 do_hibyte(f,"sbc",&p->q2,t);
4563 }
4564 emit(f,"\tbvc\t%s%d\n",labprefix,++label);
4565 emit(f,"\teor\t#128\n");
4566 emit(f,"%s%d:\n",labprefix,label);
4567 if(bc==BLT)
4568 emit(f,"\tbmi\t%s%d\n",labprefix,bout);
4569 else if(bc==BGE)
4570 emit(f,"\tbpl\t%s%d\n",labprefix,bout);
4571 else
4572 ierror(0);
4573 if(pacc){
4574 reload_acc(f);
4575 add_cmplist(bout,branch->typf,pacc);
4576 }
4577 continue;
4578 }
4579 ierror(0);
4580 }
4581
4582
4583 if((c==ADD||c==SUB)&&ISRIDX(z)&&isconst(q2)){
4584 eval_const(&p->q2.val,t);
4585 if(zmeqto(vmax,l2zm(-1L))){
4586 vmax=Z1; vumax=ZU1;
4587 if(c==ADD) c=SUB; else c=ADD;
4588 }
4589 if(zmeqto(vmax,Z1)&&zumeqto(vumax,ZU1)){
4590 if(indirect(&p->q1)){
4591 get_acc(f,p,CHAR);
4592 load_reg(f,p->z.reg,&p->q1,t);
4593 }else
4594 do_lobyte(f,"ldx",&p->q1,t);
4595 emit(f,"\t%s%s\n",(c==ADD)?"in":"de",mregnames[p->z.reg]);
4596 continue;
4597 }
4598 }
4599
4600 if((c==LSHIFT||c==RSHIFT)&&isconst(q2)&&
4601 (
4602 (isreg(q1)&&isreg(z)&&p->q1.reg==p->z.reg&&p->z.reg!=ra&&p->z.reg!=rax)||
4603 (!indirect(&p->q1)&&compare_objects(&p->q1,&p->z))
4604 )
4605 ){
4606 long l;
4607 eval_const(&p->q2.val,q2typ(p));
4608 l=zm2l(vmax);
4609 /*TODO: allow larger types */
4610 if((l<3||(iszpage(&p->z)&&l<5))&&(t&NQ)<=LONG){
4611 if(c==RSHIFT&&(!c02&&!(t&UNSIGNED)))
4612 get_acc(f,p,CHAR);
4613 incmem(f,&p->z,t,c,l);
4614 continue;
4615 }
4616 }
4617
4618 if(c==LSHIFT||c==RSHIFT){
4619 long l=-1,m;int loop=0,r=0,r2=0,r3=0,outl=0,same=0;
4620 if(isconst(q2)){
4621 eval_const(&p->q2.val,q2typ(p));
4622 l=zm2l(vmax);
4623 loop=0;
4624 }else
4625 loop=1;
4626 if(l>=0&&optsize){
4627 if(c==LSHIFT&&(l&7)>6)
4628 loop=1;
4629 else if(c==RSHIFT&&(t&UNSIGNED)&&(l&7)>3)
4630 loop=1;
4631 else if(c==RSHIFT&&!(t&UNSIGNED)&&(l&7)>2)
4632 loop=1;
4633 }
4634
4635 if(ISLONG(t)){
4636 if(!indirect(&p->z)&&
4637 (isreg(z)||(p->z.flags&(VAR|DREFOBJ))==VAR)&&
4638 (iszpage(&p->z)||(l&7)<=2)&&
4639 (!(p->q2.flags&REG)||!(p->z.flags&REG)||p->q2.reg!=p->z.reg)&&
4640 (!(p->q2.flags&VAR)||!(p->z.flags&VAR)||p->q2.v!=p->z.v)
4641 ){
4642 if(isreg(z))
4643 strcpy(mregnames[REGDUMMY1],mregnames[p->z.reg]);
4644 else if(p->z.v->storage_class==STATIC)
4645 sprintf(mregnames[REGDUMMY1],"%s%ld",labprefix,zm2l(p->z.v->offset));
4646 else
4647 sprintf(mregnames[REGDUMMY1],"%s%s",idprefix,p->z.v->identifier);
4648 strcpy(mregnames[REGDUMMY2],mregnames[REGDUMMY1]);
4649 strcpy(mregnames[REGDUMMY3],mregnames[REGDUMMY1]);
4650 strcat(mregnames[REGDUMMY1],"+1");
4651 strcat(mregnames[REGDUMMY2],"+2");
4652 if(c!=RSHIFT||(t&UNSIGNED))
4653 strcat(mregnames[REGDUMMY3],"+3");
4654 if(c==RSHIFT&&!(t&UNSIGNED)){
4655 r=REGDUMMY2;r2=REGDUMMY1;r3=REGDUMMY3;
4656 }else{
4657 r=REGDUMMY1;r2=REGDUMMY2;r3=REGDUMMY3;
4658 }
4659 if(compare_objects(&p->q1,&p->z)) same=1;
4660 }else{
4661 r2=get_reg(f,p,CHAR);
4662 r3=get_reg(f,p,CHAR);
4663 }
4664 }
4665 if(!ISCHAR(t)&&r2!=REGDUMMY1&&r2!=REGDUMMY2)
4666 r=get_reg(f,p,CHAR);
4667 if(ISLONG(t)){
4668 get_acc(f,p,CHAR);
4669 if(l>=24){
4670 if(c==LSHIFT){
4671 load_lobyte(f,&p->q1,t);
4672 emit(f,"\tsta\t%s\n",mregnames[r3]);
4673 emit(f,"\tlda\t#0\n");
4674 emit(f,"\tsta\t%s\n",mregnames[r]);
4675 emit(f,"\tsta\t%s\n",mregnames[r2]);
4676 }else if(c==RSHIFT&&!(t&UNSIGNED)){
4677 do_byte4(f,"lda",&p->q1,t);
4678 emit(f,"\tsta\t%s\n",mregnames[r3]);
4679 sety(f,0);
4680 emit(f,"\tcmp\t#0\n");
4681 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
4682 emit(f,"\tdey\n");
4683 emit(f,"%s%d:\n",labprefix,label);
4684 emit(f,"\tsty\t%s\n",mregnames[r]);
4685 emit(f,"\tsty\t%s\n",mregnames[r2]);
4686 emit(f,"\ttya\n");
4687 yval=NOVAL;
4688 }else{
4689 do_byte4(f,"lda",&p->q1,t);
4690 sety(f,0);
4691 emit(f,"\tsty\t%s\n",mregnames[r3]);
4692 emit(f,"\tsty\t%s\n",mregnames[r2]);
4693 emit(f,"\tsty\t%s\n",mregnames[r]);
4694 }
4695 }else if(l>=16){
4696 if(c==LSHIFT){
4697 load_lobyte(f,&p->q1,t);
4698 emit(f,"\tsta\t%s\n",mregnames[r2]);
4699 load_hibyte(f,&p->q1,t);
4700 emit(f,"\tsta\t%s\n",mregnames[r3]);
4701 emit(f,"\tlda\t#0\n");
4702 emit(f,"\tsta\t%s\n",mregnames[r]);
4703 }else if(c==RSHIFT&&!(t&UNSIGNED)){
4704 do_byte3(f,"lda",&p->q1,t);
4705 emit(f,"\tsta\t%s\n",mregnames[r3]);
4706 do_byte4(f,"lda",&p->q1,t);
4707 emit(f,"\tsta\t%s\n",mregnames[r2]);
4708 sety(f,0);
4709 emit(f,"\tcmp\t#0\n");
4710 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
4711 emit(f,"\tdey\n");
4712 emit(f,"%s%d:\n",labprefix,label);
4713 emit(f,"\tsty\t%s\n",mregnames[r]);
4714 emit(f,"\ttya\n");
4715 yval=NOVAL;
4716 }else{
4717 do_byte4(f,"lda",&p->q1,t);
4718 emit(f,"\tsta\t%s\n",mregnames[r]);
4719 do_byte3(f,"lda",&p->q1,t);
4720 sety(f,0);
4721 emit(f,"\tsty\t%s\n",mregnames[r2]);
4722 emit(f,"\tsty\t%s\n",mregnames[r3]);
4723 }
4724 }else if(l>=8){
4725 if(c==LSHIFT){
4726 do_byte3(f,"lda",&p->q1,t);
4727 emit(f,"\tsta\t%s\n",mregnames[r3]);
4728 load_hibyte(f,&p->q1,t);
4729 emit(f,"\tsta\t%s\n",mregnames[r2]);
4730 load_lobyte(f,&p->q1,t);
4731 emit(f,"\tsta\t%s\n",mregnames[r]);
4732 emit(f,"\tlda\t#0\n");
4733 }else if(c==RSHIFT&&!(t&UNSIGNED)){
4734 load_hibyte(f,&p->q1,t);
4735 emit(f,"\tsta\t%s\n",mregnames[r3]);
4736 do_byte3(f,"lda",&p->q1,t);
4737 emit(f,"\tsta\t%s\n",mregnames[r2]);
4738 do_byte4(f,"lda",&p->q1,t);
4739 emit(f,"\tsta\t%s\n",mregnames[r]);
4740 sety(f,0);
4741 emit(f,"\tcmp\t#0\n");
4742 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
4743 emit(f,"\tdey\n");
4744 emit(f,"%s%d:\n",labprefix,label);
4745 emit(f,"\ttya\n");
4746 yval=NOVAL;
4747 }else{
4748 if(same){
4749 load_hibyte(f,&p->q1,t);
4750 do_byte3(f,"ldy",&p->q1,t);
4751 yval=NOVAL;
4752 emit(f,"\tsty\t%s\n",mregnames[r]);
4753 do_byte4(f,"ldy",&p->q1,t);
4754 emit(f,"\tsty\t%s\n",mregnames[r2]);
4755 sety(f,0);
4756 emit(f,"\tsty\t%s\n",mregnames[r3]);
4757 }else{
4758 emit(f,"\tlda\t#0\n");
4759 emit(f,"\tsta\t%s\n",mregnames[r3]);
4760 do_byte4(f,"lda",&p->q1,t);
4761 emit(f,"\tsta\t%s\n",mregnames[r2]);
4762 do_byte3(f,"lda",&p->q1,t);
4763 emit(f,"\tsta\t%s\n",mregnames[r]);
4764 load_hibyte(f,&p->q1,t);
4765 }
4766 }
4767 }else if(c==RSHIFT&&!(t&UNSIGNED)){
4768 if(!same){
4769 load_lobyte(f,&p->q1,t);
4770 emit(f,"\tsta\t%s\n",mregnames[r3]);
4771 load_hibyte(f,&p->q1,t);
4772 emit(f,"\tsta\t%s\n",mregnames[r2]);
4773 do_byte3(f,"lda",&p->q1,t);
4774 emit(f,"\tsta\t%s\n",mregnames[r]);
4775 }
4776 do_byte4(f,"lda",&p->q1,t);
4777 }else{
4778 if(!same){
4779 do_byte4(f,"lda",&p->q1,t);
4780 emit(f,"\tsta\t%s\n",mregnames[r3]);
4781 do_byte3(f,"lda",&p->q1,t);
4782 emit(f,"\tsta\t%s\n",mregnames[r2]);
4783 load_hibyte(f,&p->q1,t);
4784 emit(f,"\tsta\t%s\n",mregnames[r]);
4785 }
4786 load_lobyte(f,&p->q1,t);
4787 }
4788 }else
4789 get_acc(f,p,t);
4790 if(!ISLONG(t)){
4791 if(l>=8){
4792 if(!ISSHORT(t)) ierror(0);
4793 if(c==LSHIFT){
4794 if(indirect(&p->q1)){
4795 load_lobyte(f,&p->q1,t);
4796 emit(f,"\ttax\n");
4797 emit(f,"\tlda\t#0\n");
4798 }else{
4799 if(isacc(q1))
4800 emit(f,"\ttax\n");
4801 else
4802 do_lobyte(f,"ldx",&p->q1,t);
4803 emit(f,"\tlda\t#0\n");
4804 }
4805 }else{
4806 load_hibyte(f,&p->q1,t);
4807 emit(f,"\tldx\t#0\n");
4808 if(!(t&UNSIGNED)){
4809 emit(f,"\tcmp\t#0\n");
4810 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
4811 emit(f,"\tdex\n");
4812 emit(f,"%s%d:\n",labprefix,label);
4813 }
4814 }
4815 }else
4816 load_acc(f,&p->q1,t);
4817 }
4818 if(l>=0) l&=7;
4819 m=l;
4820 if(ISSHORT(t)&&(l>0||loop))
4821 emit(f,"\tstx\t%s\n",mregnames[r]);
4822 if(loop){
4823 if(l>=0)
4824 sety(f,l);
4825 else{
4826 if(indirect(&p->q2)){
4827 emit(f,"\tpha\n");
4828 load_lobyte(f,&p->q2,q2typ(p));
4829 emit(f,"\ttay\n");
4830 emit(f,"\tpla\n");
4831 emit(f,"\tcpy\t#0\n");
4832 }else{
4833 emit(f,"\tldy\t");
4834 emit_lobyte(f,&p->q2,q2typ(p));
4835 emit(f,"\n");
4836 }
4837 outl=++label;
4838 emit(f,"\tbeq\t%s%d\n",labprefix,outl);
4839 }
4840 emit(f,"%s%d:\n",labprefix,++label);
4841 }else{
4842 if(ISCHAR(t))
4843 l&=7;
4844 else if(ISSHORT(t))
4845 l&=15;
4846 else
4847 l&=31;
4848 }
4849 while(l>0||loop){
4850 if(c==LSHIFT){
4851 emit(f,"\tasl\n");
4852 if(!ISCHAR(t))
4853 emit(f,"\trol\t%s\n",mregnames[r]);
4854 if(ISLONG(t)){
4855 emit(f,"\trol\t%s\n",mregnames[r2]);
4856 emit(f,"\trol\t%s\n",mregnames[r3]);
4857 }
4858 }else if(t&UNSIGNED){
4859 emit(f,"\tlsr");
4860 if(ISLONG(t)){
4861 emit(f,"\t%s\n",mregnames[r3]);
4862 emit(f,"\tror\t%s\n",mregnames[r2]);
4863 emit(f,"\tror");
4864 }
4865 if(!ISCHAR(t)){
4866 emit(f,"\t%s\n",mregnames[r]);
4867 emit(f,"\tror");
4868 }
4869 emit(f,"\n");
4870 }else{
4871 if(ISLONG(t)){
4872 if(ce02)
4873 emit(f,"\tasr\n");
4874 else{
4875 emit(f,"\tcmp\t#128\n");
4876 emit(f,"\tror\n");
4877 }
4878 emit(f,"\tror\t%s\n",mregnames[r]);
4879 emit(f,"\tror\t%s\n",mregnames[r2]);
4880 emit(f,"\tror\t%s\n",mregnames[r3]);
4881 }else{
4882 if(!ISCHAR(t)){
4883 emit(f,"\tcpx\t#128\n");
4884 emit(f,"\tror\t%s\n",mregnames[r]);
4885 }else
4886 emit(f,"\tcmp\t#128\n");
4887 emit(f,"\tror\n");
4888 }
4889 }
4890 if(loop){
4891 emit(f,"\tdey\n");
4892 emit(f,"\tbne\t%s%d\n",labprefix,label);
4893 if(outl) emit(f,"%s%d:\n",labprefix,outl);
4894 yval=0;
4895 break;
4896 }
4897 l--;
4898 }
4899 if(ISLONG(t)){
4900 if(c==RSHIFT&&!(t&UNSIGNED)){
4901 do_byte4(f,"sta",&p->z,t);
4902 if(r!=REGDUMMY2){
4903 emit(f,"\tlda\t%s\n",mregnames[r]);
4904 do_byte3(f,"sta",&p->z,t);
4905 emit(f,"\tlda\t%s\n",mregnames[r2]);
4906 store_hibyte(f,&p->z,t);
4907 emit(f,"\tlda\t%s\n",mregnames[r3]);
4908 store_lobyte(f,&p->z,t);
4909 }
4910 }else{
4911 store_lobyte(f,&p->z,t);
4912 if(r!=REGDUMMY1){
4913 emit(f,"\tlda\t%s\n",mregnames[r]);
4914 store_hibyte(f,&p->z,t);
4915 emit(f,"\tlda\t%s\n",mregnames[r2]);
4916 do_byte3(f,"sta",&p->z,t);
4917 emit(f,"\tlda\t%s\n",mregnames[r3]);
4918 do_byte4(f,"sta",&p->z,t);
4919 }
4920 }
4921 }else{
4922 if(!ISCHAR(t)&&(m>0||loop))
4923 emit(f,"\tldx\t%s\n",mregnames[r]);
4924 if(ISCHAR(t)||indirect(&p->z))
4925 store_acc(f,&p->z,t);
4926 else{
4927 store_lobyte(f,&p->z,t);
4928 if(!isreg(z)||p->z.reg!=rax){
4929 emit(f,"\tstx\t");
4930 emit_hibyte(f,&p->z,t);
4931 emit(f,"\n");
4932 }
4933 }
4934 }
4935 continue;
4936 }
4937
4938 if((c>=OR&&c<=AND)||(c>=LSHIFT&&c<=MOD)||c==ADDI2P||c==SUBIFP){
4939 char *s;int t2=t,pt=p->typf2;
4940 if(!isacc(z)){
4941 /* TODO: check other operations */
4942 if((c==ADD||c==SUB||c==AND||c==XOR||c==OR||c==ADDI2P||c==SUBIFP)&&isacc(q1)&&scratch(p->next,ra,1))
4943 ;
4944 else{
4945 if((c==ADDI2P||c==SUBIFP)&&(p->typf2&NU)==CHAR)
4946 get_acc(f,p,INT);
4947 else
4948 get_acc(f,p,CHAR);
4949 }
4950 }
4951 if(c==ADDI2P||c==SUBIFP){
4952 if(c==ADDI2P) c=ADD; else c=SUB;
4953 t=UNSIGNED|INT;
4954 if((pt&NQ)==POINTER&&(p->q1.flags&(KONST|DREFOBJ))==KONST){
4955 eval_const(&p->q1.val,POINTER);
4956 insert_const(&p->q1.val,UNSIGNED|INT);
4957 }
4958 }
4959 if(c>=OR&&c<=AND)
4960 s=logicals[c-OR];
4961 else
4962 s=arithmetics[c-LSHIFT];
4963
4964 if(ISFLOAT(t)){
4965 if(!ieee) ierror(0);
4966 t&=NQ;
4967 if(regs[LAST_PAIR]) ierror(0);
4968 get_acc(f,p,INT);
4969 regs[LAST_PAIR]=1;
4970 load_address(f,LAST_PAIR,&p->q1,t);
4971 BSET(regused,t3);
4972 BSET(regused,t4);
4973 emit(f,"\tjsr\t%s__fload%c\n",idprefix,(t==FLOAT?'s':'d'));
4974 yval=NOVAL;
4975 load_address(f,LAST_PAIR,&p->q2,t);
4976 emit(f,"\tjsr\t%s__f%s%c\n",idprefix,ename[c],(t==FLOAT?'s':'d'));
4977 yval=NOVAL;
4978 load_address(f,LAST_PAIR,&p->z,t);
4979 emit(f,"\tjsr\t%s__fstore%c\n",idprefix,(t==FLOAT?'s':'d'));
4980 yval=NOVAL;
4981 regs[LAST_PAIR]=0;
4982 continue;
4983 }else if(ISLONG(t)){
4984 long l;int cnst=0;
4985 if(c==ADD) emit(f,"\tclc\n");
4986 if(c==SUB) emit(f,"\tsec\n");
4987 if((p->q2.flags&(KONST|DREFOBJ))==KONST){
4988 eval_const(&p->q2.val,t);
4989 l=zm2l(vmax);
4990 cnst=1;
4991 }
4992 if(cnst&&c==AND&&(l&0xff)==0) emit(f,"\tlda\t#0\n");
4993 else if(cnst&&c==OR&&(l&0xff)==0xff) emit(f,"\tlda\t#255\n");
4994 else{
4995 load_lobyte(f,&p->q1,t);
4996 if(!(cnst&&((c==AND&&(l&0xff)==0xff)||(c==OR&&(l&0xff)==0)||(c==XOR&&(l&0xff)==0)))) do_lobyte(f,s,&p->q2,t);
4997 }
4998 store_lobyte(f,&p->z,t);
4999 if(cnst&&c==AND&&(l&0xff00)==0) emit(f,"\tlda\t#0\n");
5000 else if(cnst&&c==OR&&(l&0xff00)==0xff00) emit(f,"\tlda\t#255\n");
5001 else{
5002 load_hibyte(f,&p->q1,t);
5003 if(!(cnst&&((c==AND&&(l&0xff00)==0xff00)||(c==OR&&(l&0xff00)==0)||(c==XOR&&(l&0xff00)==0)))) do_hibyte(f,s,&p->q2,t);
5004 }
5005 store_hibyte(f,&p->z,t);
5006 if(cnst&&c==AND&&(l&0xff0000)==0) emit(f,"\tlda\t#0\n");
5007 else if(cnst&&c==OR&&(l&0xff0000)==0xff0000) emit(f,"\tlda\t#255\n");
5008 else{
5009 do_byte3(f,"lda",&p->q1,t);
5010 if(!(cnst&&((c==AND&&(l&0xff0000)==0xff0000)||(c==OR&&(l&0xff0000)==0)||(c==XOR&&(l&0xff0000)==0)))) do_byte3(f,s,&p->q2,t);
5011 }
5012 do_byte3(f,"sta",&p->z,t);
5013 if(cnst&&c==AND&&(l&0xff000000)==0) emit(f,"\tlda\t#0\n");
5014 else if(cnst&&c==OR&&(l&0xff000000)==0xff000000) emit(f,"\tlda\t#255\n");
5015 else{
5016 do_byte4(f,"lda",&p->q1,t);
5017 if(!(cnst&&((c==AND&&(l&0xff000000)==0xff000000)||(c==OR&&(l&0xff000000)==0)||(c==XOR&&(l&0xff000000)==0)))) do_byte4(f,s,&p->q2,t);
5018 }
5019 do_byte4(f,"sta",&p->z,t);
5020 continue;
5021 }else if(ISCHAR(t)){
5022 load_acc(f,&p->q1,t);
5023 if(c02&&(c==ADD||c==SUB)&&(p->q2.flags&(KONST|DREFOBJ))==KONST){
5024 eval_const(&p->q2.val,t);
5025 if(zmeqto(vmax,Z1)||zmeqto(vmax,l2zm(2L))){
5026 if(zmeqto(vmax,l2zm(2L)))
5027 emit(f,"\t%s\n",c==ADD?"ina":"dea");
5028 emit(f,"\t%s\n",c==ADD?"ina":"dea");
5029 store_acc(f,&p->z,t);
5030 continue;
5031 }
5032 }
5033 if(c==ADD) emit(f,"\tclc\n");
5034 if(c==SUB) emit(f,"\tsec\n");
5035 if(isreg(q2)&&ISIDX(p->q2.reg)){
5036 int r=get_reg(f,p,CHAR);
5037 emit(f,"\tst%s\t%s\n",mregnames[p->q2.reg],mregnames[r]);
5038 p->q2.flags=REG;
5039 p->q2.reg=r;
5040 }
5041 do_lobyte(f,s,&p->q2,t);
5042 store_acc(f,&p->z,t);
5043 }else if(c==ADD||c==SUB){
5044 int a,r;long l=1;
5045 if(isconst(q2)){
5046 eval_const(&p->q2.val,t2);
5047 l=zm2l(vmax);
5048 if(isacc(z)&&(l&0xffff)<=768){
5049 load_acc(f,&p->q1,t);
5050 if(c==ADD){
5051 if(l&0xff)
5052 emit(f,"\tclc\n\tadc\t#%d\n",(int)(l&255));
5053 l&=0xffff;
5054 if(l==256){emit(f,"\tinx\n");continue;}
5055 if(l==512){emit(f,"\tinx\n\tinx\n");continue;}
5056 if(l==768){emit(f,"\tinx\n\tinx\n\tinx\n");continue;}
5057 if(l<256){++label;emit(f,"\tbcc\t%s%d\n\tinx\n%s%d:\n",labprefix,label,labprefix,label);continue;}
5058 if(l<512){++label;emit(f,"\tinx\n\tbcc\t%s%d\n\tinx\n%s%d:\n",labprefix,label,labprefix,label);continue;}
5059 if(l<768){++label;emit(f,"\tinx\n\tinx\n\tbcc\t%s%d\n\tinx\n%s%d:\n",labprefix,label,labprefix,label);continue;}
5060 }else{
5061 if(l&0xff)
5062 emit(f,"\tsec\n\tsbc\t#%d\n",(int)(l&255));
5063 l&=0xffff;
5064 if(l==256){emit(f,"\tdex\n");continue;}
5065 if(l==512){emit(f,"\tdex\n\tdex\n");continue;}
5066 if(l==768){emit(f,"\tdex\n\tdex\n\tdex\n");continue;}
5067 if(l<256){++label;emit(f,"\tbcs\t%s%d\n\tdex\n%s%d:\n",labprefix,label,labprefix,label);continue;}
5068 if(l<512){++label;emit(f,"\tdex\n\tbcs\t%s%d\n\tdex\n%s%d:\n",labprefix,label,labprefix,label);continue;}
5069 if(l<768){++label;emit(f,"\tdex\n\tdex\n\tbcs\t%s%d\n\tdex\n%s%d:\n",labprefix,label,labprefix,label);continue;}
5070 }
5071 }
5072 l&=0xff00;
5073 }
5074 if(isreg(z)&&p->z.reg==rax) a=1; else a=0;
5075 if((t2&NU)==CHAR&&(p->q2.flags&(KONST|DREFOBJ))!=KONST){
5076 get_acc(f,p,INT);
5077 emit(f,"\tldx\t#0\n");
5078 load_lobyte(f,&p->q2,t);
5079 emit(f,"\tbpl\t%s%d\n",labprefix,++label);
5080 emit(f,"\tdex\n");
5081 emit(f,"%s%d:\n",labprefix,label);
5082 if(c==ADD){
5083 if(c==ADD) emit(f,"\tclc\n"); else emit(f,"\tsec\n");
5084 do_lobyte(f,s,&p->q1,t);
5085 if(isacc(z))
5086 emit(f,"\tpha\n");
5087 else
5088 store_lobyte(f,&p->z,t);
5089 emit(f,"\ttxa\n");
5090 do_hibyte(f,s,&p->q1,t);
5091 store_hibyte(f,&p->z,t);
5092 if(ISFPOINTER(pt)&&!compare_objects(&p->q1,&p->z)){
5093 do_byte3(f,"lda",&p->q1,pt);
5094 do_byte3(f,"sta",&p->z,pt);
5095 }
5096 if(isacc(z))
5097 emit(f,"\tpla\n");
5098 continue;
5099 }
5100 r=get_reg(f,p,CHAR);
5101 emit(f,"\tstx\t%s\n",mregnames[r]);
5102 }
5103 load_lobyte(f,&p->q1,t);
5104 if(c==ADD) emit(f,"\tclc\n"); else emit(f,"\tsec\n");
5105 do_lobyte(f,s,&p->q2,t2);
5106 store_lobyte(f,&p->z,t);
5107 if(l==0&&isreg(q1)&&isreg(z)&&p->q1.reg==p->z.reg){
5108 if(c==ADD){
5109 emit(f,"\tbcc\t%s%d\n",labprefix,++label);
5110 if(a)
5111 emit(f,"\tinx\n");
5112 else{
5113 /*if(!reg_pair(p->z.reg,&rp)) ierror(0);*/
5114 emit(f,"\tinc\t%s+1\n",mregnames[p->z.reg]);
5115 }
5116 }else{
5117 emit(f,"\tbcs\t%s%d\n",labprefix,++label);
5118 if(a)
5119 emit(f,"\tdex\n");
5120 else{
5121 if(!reg_pair(p->z.reg,&rp)) ierror(0);
5122 emit(f,"\tdec\t%s\n",mregnames[rp.r2]);
5123 }
5124 }
5125 emit(f,"%s%d:\n",labprefix,label);
5126 }else{
5127 if(a==1) emit(f,"\tpha\n");
5128 if((t2&NQ)==CHAR){
5129 if(t2&UNSIGNED){
5130 load_hibyte(f,&p->q1,t);
5131 emit(f,"\t%s\t#0\n",s);
5132 }else{
5133 load_hibyte(f,&p->q1,t);
5134 if((p->q2.flags&(KONST|DREFOBJ))==KONST){
5135 eval_const(&p->q2.val,t2);
5136 if(zmleq(Z0,vmax))
5137 emit(f,"\t%s\t#0\n",s);
5138 else
5139 emit(f,"\t%s\t#255\n",s);
5140 }else{
5141 emit(f,"\t%s\t%s\n",s,mregnames[r]);
5142 }
5143 }
5144 }else{
5145 load_hibyte(f,&p->q1,t);
5146 do_hibyte(f,s,&p->q2,t2);
5147 }
5148 store_hibyte(f,&p->z,t);
5149 if(a==1) emit(f,"\tpla\n");
5150 if(ISFPOINTER(pt)&&p->code!=SUBPFP){
5151 if(!compare_objects(&p->q1,&p->z)){
5152 do_byte3(f,"lda",&p->q1,FPOINTER);
5153 do_byte3(f,"sta",&p->z,FPOINTER);
5154 }
5155 }
5156 }
5157 }else{
5158 long l=-1;int dello=0;
5159 if(c!=AND&&c!=OR&&c!=XOR) ierror(0);
5160 if((p->q2.flags&(KONST|DREFOBJ))==KONST){
5161 eval_const(&p->q2.val,t);
5162 l=zm2l(vmax)&0xffff;
5163 }
5164 if(l>0&&((c==AND&&(l&0xFF)==0)||(c==OR&&(l&0xFF)==0xFF))){
5165 dello=1;
5166 }else if(l>0&&((c==AND&&(l&0xFF)==0xFF)||((c==OR||c==XOR)&&(l&0xFF)==0))){
5167 if(!compare_objects(&p->q1,&p->z)){
5168 load_lobyte(f,&p->q1,t);
5169 store_lobyte(f,&p->z,t);
5170 }
5171 }else{
5172 load_lobyte(f,&p->q1,t);
5173 do_lobyte(f,s,&p->q2,t);
5174 store_lobyte(f,&p->z,t);
5175 }
5176 if(l>0&&((c==AND&&(l&0xFF00)==0)||(c==OR&&(l&0xFF00)==0xFF00))){
5177 int val=(c==AND)?0:255;
5178 if(isacc(z)){
5179 emit(f,"\tldx\t#%d\n",val);
5180 }else{
5181 emit(f,"\tlda\t#%d\n",val);
5182 store_hibyte(f,&p->z,t);
5183 }
5184 }else if(l>0&&((c==AND&&(l&0xFF00)==0xFF00)||((c==OR||c==XOR)&&(l&0xFF00)==0))){
5185 if(isacc(z)&&!indirect(&p->q1)){
5186 do_hibyte(f,"ldx",&p->q1,t);
5187 }else{
5188 if(!compare_objects(&p->q1,&p->z)){
5189 if(!dello&&isacc(z))
5190 emit(f,"\tpha\n");
5191 load_hibyte(f,&p->q1,t);
5192 store_hibyte(f,&p->z,t);
5193 if(!dello&&isacc(z))
5194 emit(f,"\tpla\n");
5195 }
5196 }
5197 }else{
5198 if(!dello&&isacc(z))
5199 emit(f,"\tpha\n");
5200 load_hibyte(f,&p->q1,t);
5201 do_hibyte(f,s,&p->q2,t);
5202 store_hibyte(f,&p->z,t);
5203 if(!dello&&isacc(z))
5204 emit(f,"\tpla\n");
5205 }
5206 if(dello){
5207 emit(f,"\tlda\t#%d\n",(c==AND)?0:255);
5208 store_lobyte(f,&p->z,t);
5209 }
5210 }
5211 continue;
5212 }
5213 pric2(stdout,p);
5214 ierror(0);
5215 }
5216
5217 function_bottom(f,v,localsize);
5218
5219 for(c=1;c<=MAXR;c++){
5220 if(regsa[c]||regused[c]){
5221 BSET(regs_modified,c);
5222 }
5223 }
5224
5225 if(stack_valid){
5226 if(!v->fi) v->fi=new_fi();
5227 v->fi->flags|=ALL_STACK;
5228 v->fi->stack1=stack;
5229 }
5230 }
5231
5232 free_IC(mi);
5233
5234 emit(f,"; stacksize=%lu%s\n",zum2ul(stack),stack_valid?"":"+??");
5235}
5236
5237int shortcut(int code,int typ)
5238{
5239 if(code==COMPARE||code==MULT||code==ADD||code==SUB||code==AND||code==OR||code==XOR||code==LSHIFT||code==RSHIFT||code==MINUS||code==KOMPLEMENT||code==NEGATION)
5240 return 1;
5241
5242 return 0;
5243}
5244
5245static int fattr(type *p,char *s)
5246{
5247 if(p->attr&&strstr(p->attr,s))
5248 return 1;
5249 if(p->next)
5250 return fattr(p->next,s);
5251 else
5252 return 0;
5253}
5254
5255int reg_parm(struct reg_handle *m, struct Typ *t,int vararg,struct Typ *d)
5256{
5257 int f;
5258
5259 if(vararg)
5260 return 0;
5261 f=t->flags&NQ;
5262 if(OLDFP&&ISFLOAT(f)) return 0;
5263 if(d&&fattr(d,"__stackparms__"))
5264 return 0;
5265 if(d&&fattr(d,"__cc65__")){
5266 m->regs++;
5267 printf("arg=%d cnt=%d\n",m->regs,d->exact->count);
5268 if(m->regs==d->exact->count-1){
5269 if(ISCHAR(t->flags))
5270 return ra;
5271 if(ISSHORT(t->flags))
5272 return rax;
5273 }
5274 return 0;
5275 }
5276 if(ISCHAR(f)){
5277 if(!t->exact){
5278 if(m->regs>=GPR_ARGS-1)
5279 return 0;
5280 f=FIRST_GPR+m->regs;
5281 m->regs+=2;
5282 return f;
5283 }else{
5284 if(m->regs>=GPR_ARGS)
5285 return 0;
5286 else
5287 return FIRST_GPR+m->regs++;
5288 }
5289 }
5290 if(ISSHORT(f)||f==POINTER){
5291 if(m->regs>=GPR_ARGS-1)
5292 return 0;
5293 else{
5294 if(m->regs&1) m->regs+=1;
5295 m->regs+=2;
5296 return FIRST_PAIR+m->regs/2-1;
5297 }
5298 }
5299 if(f==FPOINTER||f==LONG||f==FLOAT||(!ieee&&(f==DOUBLE||f==LDOUBLE))){
5300 if(m->bregs>=4)
5301 return 0;
5302 else
5303 return FIRST_BIG+m->bregs++;
5304 }
5305 if(f==LLONG||(ieee&&(f==DOUBLE||f==LDOUBLE))){
5306 if(m->bregs>=3)
5307 return 0;
5308 else{
5309 if(m->bregs&1) m->bregs++;
5310 m->bregs+=2;
5311 return FIRST_BIGP+m->bregs/2-1;
5312 }
5313 }
5314 return 0;
5315}
5316
5317int handle_pragma(const char *s)
5318{
5319 static char sec[SECLEN];
5320 int i;
5321 if(sscanf(s,"section %127s",sec)==1){
5322 if(!strcmp(sec,"default"))
5323 use_sec=0;
5324 else
5325 use_sec=sec;
5326 return 1;
5327 }
5328 if(sscanf(s,"bank %d",&i)==1){
5329 use_bank=i;
5330 return 1;
5331 }
5332}
5333void cleanup_cg(FILE *f)
5334{
5335 int i;
5336 struct fpconstlist *p=firstfpc;
5337
5338 if(f&&p){
5339 emit(f,rodataname);emit(f,"\n");
5340 section=RODATA;
5341 }
5342 while(p=firstfpc){
5343 emit(f,"%s%d:\n\tword\t",labprefix,p->label);
5344 if(ieee)
5345 emit_ieee(f,&p->val,p->t);
5346 else{
5347 int words=zm2l(sizetab[p->t&NQ])/2;
5348 eval_const(&p->val,p->t);
5349 if(ISFLOAT(p->t)) cnv_fp();
5350 for(i=0;i<words;i++){
5351 emit(f,"%ld",zm2l(vmax)&0xffff);
5352 if(i<words-1){emit(f,",");vmax=zmrshift(vmax,l2zm(16L));}
5353 }
5354 emit(f,"\n");
5355 /*emit(f,"%ld,%ld\n",zm2l(vmax)&0xffff,zm2l(zmrshift(vmax,l2zm(16L)))&0xffff);*/
5356 }
5357 firstfpc=p->next;
5358 free(p);
5359 }
5360
5361 emit(f,"\tzpage\t%s\n",mregnames[sp]);
5362 for(i=FIRST_GPR;i<=LAST_GPR;i++)
5363 emit(f,"\tzpage\t%s\n",mregnames[i]);
5364 for(i=FIRST_BIG;i<=LAST_BIG;i++)
5365 emit(f,"\tzpage\t%s\n",mregnames[i]);
5366
5367}
5368void cleanup_db(FILE *f)
5369{
5370 if(f) section=-1;
5371}
5372
5373static char *zops[]={
5374 "adc","and","asl","bit","eor","lda","ora",
5375 "tax","txa","tay","tya","sbc"};
5376
5377static int setszflag(char *op)
5378{
5379 int i;
5380 for(i=0;i<sizeof(zops)/sizeof(zops[0]);i++)
5381 if(!strcmp(op,zops[i]))
5382 return 1;
5383 return 0;
5384}
5385
5386static char *zxops[]={
5387 "tax","txa","ldx","inx","dex"};
5388
5389static int setszxflag(char *op)
5390{
5391 int i;
5392 for(i=0;i<sizeof(zxops)/sizeof(zxops[0]);i++)
5393 if(!strcmp(op,zxops[i]))
5394 return 1;
5395 return 0;
5396}
5397
5398enum peepf { NEEDSAME = 1, REMOVE1ST = 2};
5399struct peeps {char *s1,*s2,*r;enum peepf flags;};
5400
5401
5402
5403int emit_peephole(void)
5404{
5405 int entries,i,j;
5406 char *asmline[EMIT_BUF_DEPTH];
5407 char buf1[1024],buf2[1024];
5408 char op1[8],op2[8];
5409 static char ca[1024],cx[1024],cy[1024],cz[1024];
5410 static int rm,disabled;
5411
5412 static struct peeps elim[]={
5413 "lda","sta",0,NEEDSAME,
5414 "ldx","stx",0,NEEDSAME,
5415 "ldy","sty",0,NEEDSAME,
5416 "ldz","stz",0,NEEDSAME,
5417 "ldq","stq",0,NEEDSAME,
5418 "sta","sta",0,NEEDSAME,
5419 "stx","stx",0,NEEDSAME,
5420 "sty","sty",0,NEEDSAME,
5421 "stz","stz",0,NEEDSAME,
5422 "stq","stq",0,NEEDSAME,
5423 "sta","lda",0,NEEDSAME,
5424 "stx","ldx",0,NEEDSAME,
5425 "sty","ldy",0,NEEDSAME,
5426 "stz","ldz",0,NEEDSAME,
5427 "stq","ldq",0,NEEDSAME,
5428 "txa","tax",0,0,
5429 "tax","txa",0,0,
5430 "tay","tya",0,0,
5431 "tya","tay",0,0,
5432 "tza","taz",0,0,
5433 "taz","tza",0,0,
5434 "lda","lda",0,REMOVE1ST,
5435 "ldx","ldx",0,REMOVE1ST,
5436 "ldy","ldy",0,REMOVE1ST,
5437 "ldz","ldz",0,REMOVE1ST,
5438 "ldq","ldq",0,REMOVE1ST,
5439 "lda","ldq",0,REMOVE1ST,
5440 "ldx","ldq",0,REMOVE1ST,
5441 "ldy","ldq",0,REMOVE1ST,
5442 "lda","pla",0,REMOVE1ST,
5443 "ldx","plx",0,REMOVE1ST,
5444 "ldy","ply",0,REMOVE1ST,
5445 "ldz","plz",0,REMOVE1ST,
5446 "lda","txa",0,REMOVE1ST,
5447 "lda","tya",0,REMOVE1ST,
5448 "lda","tza",0,REMOVE1ST,
5449 "ldx","tax",0,REMOVE1ST,
5450 "ldy","tay",0,REMOVE1ST,
5451 "ldz","taz",0,REMOVE1ST,
5452 "tay","ldy",0,REMOVE1ST,
5453 "tax","ldx",0,REMOVE1ST,
5454 "taz","ldz",0,REMOVE1ST,
5455 "txa","lda",0,REMOVE1ST,
5456 "tya","lda",0,REMOVE1ST,
5457 "tza","lda",0,REMOVE1ST,
5458 "lda","ldx","\ttax\n",NEEDSAME,
5459 "lda","ldy","\ttay\n",NEEDSAME,
5460 "lda","ldz","\ttaz\n",NEEDSAME,
5461 "ldx","lda","\ttxa\n",NEEDSAME,
5462 "ldy","lda","\ttya\n",NEEDSAME,
5463 "ldz","lda","\ttza\n",NEEDSAME,
5464 "sta","ldx","\ttax\n",NEEDSAME,
5465 "sta","ldy","\ttay\n",NEEDSAME,
5466 "sta","ldz","\ttaz\n",NEEDSAME,
5467 "stx","lda","\ttxa\n",NEEDSAME,
5468 "sty","lda","\ttya\n",NEEDSAME,
5469 "stz","lda","\ttza\n",NEEDSAME, /* must be last */
5470 };
5471
5472 if(nopeep) return 0;
5473
5474 /* activate optimization that is not valid for c02 */
5475 if(!ce02) elim[sizeof(elim)/sizeof(elim[0])-1].r="\tlda\t#0\n";
5476
5477 i=emit_l;
5478 if(emit_f==0)
5479 entries=i-emit_f+1;
5480 else
5481 entries=EMIT_BUF_DEPTH;
5482 asmline[0]=emit_buffer[i];
5483
5484 if(!strcmp(asmline[0],";startinline\n")) disabled=1;
5485 if(!strcmp(asmline[0],";endinline\n")) disabled=0;
5486 if(disabled) return 0;
5487
5488 buf1[0]=0;op1[0]=0;
5489 if((j=sscanf(asmline[0]," %6s %999s",op1,buf1))>=1){
5490 /*printf("a=%s x=%s y=%s z=%s\n",ca,cx,cy,cz);
5491 printf("\t\t%s %s\n",op1,buf1);*/
5492 if(!strcmp(op1,"lda")){
5493 if(buf1[0]=='#'){
5494 if(!rm&&!strcmp(buf1,ca)){remove_asm();return rm=1;}
5495 if(!rm&&!strcmp(buf1,cx)){strcpy(asmline[0],"\ttxa\n");return rm=1;}
5496 if(!rm&&!strcmp(buf1,cy)){strcpy(asmline[0],"\ttya\n");return rm=1;}
5497 if(!rm&&!strcmp(buf1,cz)){strcpy(asmline[0],"\ttza\n");return rm=1;}
5498 strcpy(ca,buf1);
5499 }else ca[0]=0;
5500 }else if(!strcmp(op1,"ldx")){
5501 if(buf1[0]=='#'){
5502 if(!rm&&!strcmp(buf1,cx)){remove_asm();return rm=1;}
5503 if(!rm&&!strcmp(buf1,ca)){strcpy(asmline[0],"\ttax\n");return rm=1;}
5504 strcpy(cx,buf1);
5505 }else cx[0]=0;
5506 }else if(!strcmp(op1,"ldy")){
5507 if(buf1[0]=='#'){
5508 if(!rm&&!strcmp(buf1,cy)){remove_asm();return rm=1;}
5509 if(!rm&&!strcmp(buf1,ca)){strcpy(asmline[0],"\ttay\n");return rm=1;}
5510 strcpy(cy,buf1);
5511 }else cy[0]=0;
5512 }else if(!strcmp(op1,"ldz")){
5513 if(buf1[0]=='#'){
5514 if(!rm&&!strcmp(buf1,cz)){remove_asm();return rm=1;}
5515 if(!rm&&!strcmp(buf1,ca)){strcpy(asmline[0],"\ttaz\n");return rm=1;}
5516 strcpy(cz,buf1);
5517 }else cz[0]=0;
5518 }else{
5519 static char clobbernone[]="asw bit clc cld cli clv cmp cpx cpy dec deq dew inc inq inw nop pha php phw phz plp sec sed sei sta stq stx sty";
5520 static char clobbera[]="adc and asl asr eor lsr ora pla rol ror sbc txa tya tza";
5521 static char clobberx[]="dex inx tax tsx";
5522 static char clobbery[]="dey iny tay";
5523 static char clobberz[]="dez inz taz";
5524 if(strstr(clobbernone,op1)){
5525 }else if(strstr(clobbera,op1))
5526 ca[0]=0;
5527 else if(strstr(clobberx,op1))
5528 cx[0]=0;
5529 else if(strstr(clobbery,op1))
5530 cy[0]=0;
5531 else if(strstr(clobberz,op1))
5532 cz[0]=0;
5533 else
5534 ca[0]=cx[0]=cy[0]=cz[0]=0;
5535 }
5536 }else{
5537 ca[0]=cx[0]=cy[0]=cz[0]=0;
5538 }
5539
5540 rm=0;
5541
5542 if(sscanf(asmline[0]," %6s %999s",op1,buf1)==2&&!strcmp(op1,"and")&&!strcmp(buf1,"#0")){
5543 strcpy(asmline[0],"\tlda\t#0\n");
5544 return rm=1;
5545 }
5546
5547 if(entries>=2){
5548 i--;
5549 if(i<0) i=EMIT_BUF_DEPTH-1;
5550 asmline[1]=emit_buffer[i];
5551
5552
5553 if(!strcmp(asmline[0],"; volatile barrier\n")&&!strcmp(asmline[0],asmline[1])){
5554 remove_asm();
5555 return rm=1;
5556 }
5557
5558 if(sscanf(asmline[0]," %6s",op1)==1&&!strcmp(op1,"rts")&&
5559 sscanf(asmline[1]," %6s %999s",op2,buf2)==2&&!strcmp(op2,"jsr")){
5560 sprintf(asmline[1],"\tjmp\t%s\n",buf2);
5561 remove_asm();
5562 return rm=1;
5563 }
5564
5565 for(j=0;j<sizeof(elim)/sizeof(elim[0]);j++){
5566 if(elim[j].flags&NEEDSAME){
5567 if(sscanf(asmline[0]," %6s %999s",op2,buf2)==2&&
5568 sscanf(asmline[1]," %6s %999s",op1,buf1)==2&&
5569 !strcmp(op1,elim[j].s1)&&!strcmp(op2,elim[j].s2)&&
5570 !strcmp(buf1,buf2)){
5571 if(elim[j].r){
5572 strcpy(asmline[0],elim[j].r);
5573 }else{
5574 if(elim[j].flags&REMOVE1ST)
5575 strcpy(asmline[1],asmline[0]);
5576 remove_asm();
5577 }
5578 return rm=1;
5579 }
5580 }else{
5581 if(sscanf(asmline[1]," %6s",op1)==1&&
5582 sscanf(asmline[0]," %6s",op2)==1&&
5583 !strcmp(op1,elim[j].s1)&&!strcmp(op2,elim[j].s2)){
5584 if(elim[j].flags&REMOVE1ST)
5585 strcpy(asmline[1],asmline[0]);
5586 remove_asm();
5587 return rm=1;
5588 }
5589 }
5590 }
5591
5592
5593 }
5594
5595 if(entries>=3){
5596 i--;
5597 if(i<0) i=EMIT_BUF_DEPTH-1;
5598 asmline[2]=emit_buffer[i];
5599 if(sscanf(asmline[0]," %6s %999s",op1,buf1)==2){
5600#if 0
5601 if(!strcmp(op1,"lda")&&buf1[0]=='#'){
5602 if(sscanf(asmline[1]," %6s %999s",op2,buf2)==2&&
5603 !strcmp(op2,"sta")){
5604 if(sscanf(asmline[2]," %6s %999s",op2,buf2)==2&&
5605 !strcmp(op2,"lda")&&!strcmp(buf1,buf2)){
5606 remove_asm();
5607 return rm=1;
5608 }
5609 }
5610 }
5611#endif
5612 if(!strcmp(op1,"beq")||!strcmp(op1,"bne")){
5613 if(sscanf(asmline[1]," %6s %999s",op2,buf2)==2&&
5614 !strcmp(op2,"cmp")&&!strcmp(buf2,"#0")){
5615 if(sscanf(asmline[2]," %6s",op2)==1&&
5616 setszflag(op2)){
5617 strcpy(asmline[1],asmline[0]);
5618 remove_asm();
5619 return rm=1;
5620 }
5621 }
5622 }
5623 if(!strcmp(op1,"beq")||!strcmp(op1,"bne")){
5624 if(sscanf(asmline[1]," %6s %999s",op2,buf2)==2&&
5625 !strcmp(op2,"cpx")&&!strcmp(buf2,"#0")){
5626 if(sscanf(asmline[2]," %6s",op2)==1&&
5627 setszxflag(op2)){
5628 strcpy(asmline[1],asmline[0]);
5629 remove_asm();
5630 return rm=1;
5631 }
5632 }
5633 }
5634 }
5635 }
5636 if(entries>=4){
5637 i--;
5638 if(i<0) i=EMIT_BUF_DEPTH-1;
5639 asmline[3]=emit_buffer[i];
5640 }
5641 if(entries>=5){
5642 i--;
5643 if(i<0) i=EMIT_BUF_DEPTH-1;
5644 asmline[4]=emit_buffer[i];
5645 if(sscanf(asmline[0]," %s %s",op1,buf1)>=1){
5646 if(!strcmp(op1,"lda")||!strcmp(op1,"pla")||!strcmp(op1,"txa")||!strcmp(op1,"tya")){
5647 if(sscanf(asmline[1]," %s %s",op1,buf1)>=1&&!strcmp(op1,"pla")&&
5648 sscanf(asmline[2]," %s %s",op1,buf1)>=1&&!strcmp(op1,"tay")&&
5649 sscanf(asmline[3]," %s %s",op1,buf1)>=1&&!strcmp(op1,"txa")&&
5650 sscanf(asmline[4]," %s %s",op1,buf1)>=1&&!strcmp(op1,"pha")){
5651 strcpy(asmline[4],asmline[3]);
5652 strcpy(asmline[3],asmline[2]);
5653 strcpy(asmline[2],asmline[0]);
5654 remove_asm();
5655 remove_asm();
5656 return rm=1;
5657 }
5658 }
5659 }
5660 }
5661 return 0;
5662}
5663
5664/* Return name of library function, if this node should be
5665 implemented via libcall. */
5666char *use_libcall(int c,int t,int t2)
5667{
5668 static char fname[16];
5669 char *ret=0;
5670
5671 if(c==COMPARE){
5672 if((t&NQ)==LLONG||(ISFLOAT(t)&&!ieee)){
5673 sprintf(fname,"__cmp%s%s%ld",(t&UNSIGNED)?"u":"s",ISFLOAT(t)?"flt":"int",zm2l(sizetab[t&NQ])*8);
5674 ret=fname;
5675 }
5676 }else{
5677 t&=NU;
5678 t2&=NU;
5679 if(ISSHORT(t)&&c!=MULT&&c!=DIV&&c!=MOD&&!ISFLOAT(t2))
5680 return 0;
5681 if(ISLONG(t)&&c!=MULT&&c!=DIV&&c!=MOD&&!ISFLOAT(t2))
5682 return 0;
5683
5684 if(!ieee&&ISFLOAT(t)) t=FLOAT;
5685 if(t==LDOUBLE) t=DOUBLE;
5686 if(t2==LDOUBLE) t2=DOUBLE;
5687 if(!ieee&&ISFLOAT(t2)) t2=FLOAT;
5688 if(c==CONVERT){
5689 if(t==t2) return 0;
5690 if(t==FLOAT&&t2==DOUBLE) return "__flt64toflt32";
5691 if(t==DOUBLE&&t2==FLOAT) return "__flt32toflt64";
5692
5693 if(ISFLOAT(t)){
5694 sprintf(fname,"__%cint%ldtoflt%d",(t2&UNSIGNED)?'u':'s',zm2l(sizetab[t2&NQ])*8,(t==FLOAT)?32:64);
5695 ret=fname;
5696 }
5697 if(ISFLOAT(t2)){
5698 sprintf(fname,"__flt%dto%cint%ld",((t2&NU)==FLOAT)?32:64,(t&UNSIGNED)?'u':'s',zm2l(sizetab[t&NQ])*8);
5699 ret=fname;
5700 }
5701 }
5702 if(c==MULT&&(t&NQ)==CHAR&&!m65) return "__mulint8";
5703 if((t&NQ)==SHORT||(t&NQ)==INT||(t&NQ)==LONG||(t&NQ)==LLONG||(!ieee&&ISFLOAT(t))){
5704 if((c>=LSHIFT&&c<=MOD)||(c>=OR&&c<=AND)||c==KOMPLEMENT||c==MINUS){
5705 if(m65&&ISLONG(t)&&(c==MULT||(c==DIV&&!divbug&&(t&UNSIGNED)))) return 0;
5706 if(m65&&c==MULT&&ISSHORT(t)) return 0;
5707 if(t==(UNSIGNED|LLONG)&&(c==MULT||c==DIV||c==MOD||c==RSHIFT)){
5708 sprintf(fname,"__%suint64",ename[c]);
5709 ret=fname;
5710 }else if((t&NQ)==LLONG){
5711 sprintf(fname,"__%sint64",ename[c]);
5712 ret=fname;
5713 }else if(t==(UNSIGNED|LONG)&&(c==DIV||c==MOD||c==RSHIFT)){
5714 sprintf(fname,"__%suint32",ename[c]);
5715 ret=fname;
5716 }else if((t&NQ)==LONG){
5717 sprintf(fname,"__%sint32",ename[c]);
5718 ret=fname;
5719 }else if(t==(UNSIGNED|INT)&&(c==DIV||c==MOD||c==RSHIFT)){
5720 sprintf(fname,"__%suint16",ename[c]);
5721 ret=fname;
5722 }else if((t&NQ)==INT){
5723 sprintf(fname,"__%sint16",ename[c]);
5724 ret=fname;
5725 }else{
5726 sprintf(fname,"__%s%s%s%ld",ename[c],(t&UNSIGNED)?"u":"",ISFLOAT(t)?"flt":"int",zm2l(sizetab[t&NQ])*8);
5727 ret=fname;
5728 }
5729 }
5730 }
5731 }
5732
5733 if(ret&&divbug&&(c==DIV||c==MOD)&&!ISFLOAT(t)) strcat(ret,"wo");
5734
5735 return ret;
5736}
5737
5738
5739int pointer_varadr(Var *v)
5740{
5741 int b=bank(v);
5742 if(b>=0&&b!=bankcnum&&!NOBANKVARS){
5743 if(cur_funcv&&bank(cur_funcv)!=b)
5744 return FPOINTER;
5745 }
5746 return pointer_type(v->vtyp);
5747}
5748
5749int pointer_type(struct Typ *p)
5750{
5751 struct Typ *merk=p;
5752 if(!p) ierror(0);
5753 if(LARGE) return FPOINTER;
5754 while(ISARRAY(p->flags)||ISFUNC(p->flags)) p=p->next;
5755 if(p->attr){
5756 char *s;
5757 if(strstr(p->attr,STR_HUGE)) return HPOINTER;
5758 if(strstr(p->attr,STR_FAR)) return FPOINTER;
5759 if(strstr(p->attr,STR_NEAR)) return POINTER;
5760 }
5761 return POINTER;
5762}
5763
5764unsigned char cbmconv(unsigned char x)
5765{
5766 static unsigned char ctab[256]={
5767 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x14,0x09,0x0D,0x11,0x93,0x0A,0x0E,0x0F,
5768 0x10,0x0B,0x12,0x13,0x08,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
5769 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
5770 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
5771 0x40,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
5772 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0x5B,0xBF,0x5D,0x5E,0xA4,
5773 0xAD,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
5774 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0xB3,0xDD,0xAB,0xB1,0xDF,
5775 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
5776 0x90,0x91,0x92,0x0C,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
5777 0xA0,0xA1,0xA2,0xA3,0x5F,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0x7D,0xAC,0x60,0xAE,0xAF,
5778 0xB0,0x7E,0xB2,0x7B,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0x5C,
5779 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
5780 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0xDC,0x7C,0xDE,0x7F,
5781 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
5782 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
5783 };
5784
5785 static unsigned char atab[]={0xfd,8,0x7f,0x9b,11,0x7d};
5786
5787 if(cbmascii)
5788 return ctab[x&255];
5789 else if(atascii&&x>=7&&x<=12)
5790 return atab[x-7];
5791 else
5792 return x;
5793}
5794
5795void insert_const(union atyps *p,int t)
5796/* Traegt Konstante in entprechendes Feld ein. */
5797{
5798 if(!p) ierror(0);
5799/* *p = (union atyps) 0 ; /* rfi: clear unused bits */
5800 t&=NU;
5801 if(t==CHAR) {p->vchar=vchar;return;}
5802 if(t==SHORT) {p->vshort=vshort;return;}
5803 if(t==INT) {p->vint=vint;return;}
5804 if(t==LONG) {p->vlong=vlong;return;}
5805 if(t==LLONG) {p->vllong=vllong;return;}
5806 if(t==MAXINT) {p->vmax=vmax;return;}
5807 if(t==(UNSIGNED|CHAR)) {p->vuchar=vuchar;return;}
5808 if(t==(UNSIGNED|SHORT)) {p->vushort=vushort;return;}
5809 if(t==(UNSIGNED|INT)) {p->vuint=vuint;return;}
5810 if(t==(UNSIGNED|LONG)) {p->vulong=vulong;return;}
5811 if(t==(UNSIGNED|LLONG)) {p->vullong=vullong;return;}
5812 if(t==(UNSIGNED|MAXINT)) {p->vumax=vumax;return;}
5813 if(t==FLOAT) {p->vfloat=vfloat;return;}
5814 if(t==DOUBLE) {p->vdouble=vdouble;return;}
5815 if(t==LDOUBLE) {p->vldouble=vldouble;return;}
5816 if(t==POINTER) {p->vuint=vuint;return;}
5817 if(t==FPOINTER||t==HPOINTER) {p->vulong=vulong;return;}
5818}
5819
5820void eval_const(union atyps *p,int t)
5821/* Weist bestimmten globalen Variablen Wert einer CEXPR zu. */
5822{
5823 int f=t&NQ;
5824 if(!p) ierror(0);
5825 if(f==MAXINT||(f>=CHAR&&f<=LLONG)){
5826 if(!(t&UNSIGNED)){
5827 if(f==CHAR) vmax=zc2zm(p->vchar);
5828 else if(f==SHORT)vmax=zs2zm(p->vshort);
5829 else if(f==INT) vmax=zi2zm(p->vint);
5830 else if(f==LONG) vmax=zl2zm(p->vlong);
5831 else if(f==LLONG) vmax=zll2zm(p->vllong);
5832 else if(f==MAXINT) vmax=p->vmax;
5833 else ierror(0);
5834 vumax=zm2zum(vmax);
5835 vldouble=zm2zld(vmax);
5836 }else{
5837 if(f==CHAR) vumax=zuc2zum(p->vuchar);
5838 else if(f==SHORT)vumax=zus2zum(p->vushort);
5839 else if(f==INT) vumax=zui2zum(p->vuint);
5840 else if(f==LONG) vumax=zul2zum(p->vulong);
5841 else if(f==LLONG) vumax=zull2zum(p->vullong);
5842 else if(f==MAXINT) vumax=p->vumax;
5843 else ierror(0);
5844 vmax=zum2zm(vumax);
5845 vldouble=zum2zld(vumax);
5846 }
5847 }else{
5848 if(ISPOINTER(f)){
5849 if(f==POINTER)
5850 vumax=zui2zum(p->vuint);
5851 else
5852 vumax=zul2zum(p->vulong);
5853 vmax=zum2zm(vumax);vldouble=zum2zld(vumax);
5854 }else{
5855 if(f==FLOAT) vldouble=zf2zld(p->vfloat);
5856 else if(f==DOUBLE) vldouble=zd2zld(p->vdouble);
5857 else vldouble=p->vldouble;
5858 vmax=zld2zm(vldouble);
5859 vumax=zld2zum(vldouble);
5860 }
5861 }
5862 vfloat=zld2zf(vldouble);
5863 vdouble=zld2zd(vldouble);
5864 vuchar=zum2zuc(vumax);
5865 vushort=zum2zus(vumax);
5866 vuint=zum2zui(vumax);
5867 vulong=zum2zul(vumax);
5868 vullong=zum2zull(vumax);
5869 vchar=zm2zc(vmax);
5870 vshort=zm2zs(vmax);
5871 vint=zm2zi(vmax);
5872 vlong=zm2zl(vmax);
5873 vllong=zm2zll(vmax);
5874}
5875
5876void printval(FILE *f,union atyps *p,int t)
5877/* Gibt atyps aus. */
5878{
5879 t&=NU;
5880 if(t==CHAR){fprintf(f,"C");vmax=zc2zm(p->vchar);printzm(f,vmax);}
5881 if(t==(UNSIGNED|CHAR)){fprintf(f,"UC");vumax=zuc2zum(p->vuchar);printzum(f,vumax);}
5882 if(t==SHORT){fprintf(f,"S");vmax=zs2zm(p->vshort);printzm(f,vmax);}
5883 if(t==(UNSIGNED|SHORT)){fprintf(f,"US");vumax=zus2zum(p->vushort);printzum(f,vumax);}
5884 if(t==FLOAT){fprintf(f,"F");vldouble=zf2zld(p->vfloat);printzld(f,vldouble);}
5885 if(t==DOUBLE){fprintf(f,"D");vldouble=zd2zld(p->vdouble);printzld(f,vldouble);}
5886 if(t==LDOUBLE){fprintf(f,"LD");printzld(f,p->vldouble);}
5887 if(t==INT){fprintf(f,"I");vmax=zi2zm(p->vint);printzm(f,vmax);}
5888 if(t==(UNSIGNED|INT)||t==POINTER){fprintf(f,"UI");vumax=zui2zum(p->vuint);printzum(f,vumax);}
5889 if(t==LONG){fprintf(f,"L");vmax=zl2zm(p->vlong);printzm(f,vmax);}
5890 if(t==(UNSIGNED|LONG)||t==FPOINTER||t==HPOINTER){fprintf(f,"UL");vumax=zul2zum(p->vulong);printzum(f,vumax);}
5891 if(t==LLONG){fprintf(f,"LL");vmax=zll2zm(p->vllong);printzm(f,vmax);}
5892 if(t==(UNSIGNED|LLONG)){fprintf(f,"ULL");vumax=zull2zum(p->vullong);printzum(f,vumax);}
5893 if(t==MAXINT) printzm(f,p->vmax);
5894 if(t==(UNSIGNED|MAXINT)) printzum(f,p->vumax);
5895}
5896
5897void emitval(FILE *f,union atyps *p,int t)
5898/* Gibt atyps aus. */
5899{
5900 t&=NU;
5901 if(t==CHAR){vmax=zc2zm(p->vchar);emitzm(f,vmax);}
5902 if(t==(UNSIGNED|CHAR)){vumax=zuc2zum(p->vuchar);emitzum(f,vumax);}
5903 if(t==SHORT){vmax=zs2zm(p->vshort);emitzm(f,vmax);}
5904 if(t==(UNSIGNED|SHORT)){vumax=zus2zum(p->vushort);emitzum(f,vumax);}
5905 if(t==FLOAT){vldouble=zf2zld(p->vfloat);emitzld(f,vldouble);}
5906 if(t==DOUBLE){vldouble=zd2zld(p->vdouble);emitzld(f,vldouble);}
5907 if(t==LDOUBLE){emitzld(f,p->vldouble);}
5908 if(t==INT){vmax=zi2zm(p->vint);emitzm(f,vmax);}
5909 if(t==(UNSIGNED|INT)||t==POINTER){vumax=zui2zum(p->vuint);emitzum(f,vumax);}
5910 if(t==LONG){vmax=zl2zm(p->vlong);emitzm(f,vmax);}
5911 if(t==(UNSIGNED|LONG)||t==FPOINTER||t==HPOINTER){vumax=zul2zum(p->vulong);emitzum(f,vumax);}
5912 if(t==LLONG){vmax=zll2zm(p->vllong);emitzm(f,vmax);}
5913 if(t==(UNSIGNED|LLONG)){vumax=zull2zum(p->vullong);emitzum(f,vumax);}
5914 if(t==MAXINT) emitzm(f,p->vmax);
5915 if(t==(UNSIGNED|MAXINT)) emitzum(f,p->vumax);
5916}
5917
5918void conv_typ(struct Typ *p)
5919/* Erzeugt extended types in einem Typ. */
5920{
5921 char *attr;
5922 while(p){
5923 if(ISPOINTER(p->flags)){
5924 p->flags=((p->flags&~NU)|POINTER_TYPE(p->next));
5925 if(attr=p->next->attr){
5926 if(strstr(attr,STR_NEAR))
5927 p->flags=((p->flags&~NU)|POINTER);
5928 if(strstr(attr,STR_FAR))
5929 p->flags=((p->flags&~NU)|FPOINTER);
5930 if(strstr(attr,STR_HUGE))
5931 p->flags=((p->flags&~NU)|HPOINTER);
5932 }
5933 }
5934 p=p->next;
5935 }
5936}
5937
5938void add_var_hook_post(Var *v)
5939{
5940 if(use_sec&&(v->storage_class==STATIC||v->storage_class==EXTERN)){
5941 char buf[SECLEN+32];
5942 sprintf(buf,"section(\"%s\");",use_sec);
5943 add_attr(&v->vattr,buf);
5944 }
5945 if(use_bank>=0&&(v->storage_class==STATIC||v->storage_class==EXTERN)){
5946 char buf[64];
5947 /*sprintf(buf,"section(\"bank%d\");bank(%d)",use_bank,use_bank);*/
5948 sprintf(buf,"bank(%d)",use_bank);
5949 add_attr(&v->vattr,buf);
5950 }
5951}
5952
5953int decide_reverse(zmax v)
5954{
5955 if(zmeqto(v,Z1)||zmeqto(v,l2zm(2L)))
5956 return 1;
5957 if(optspeed)
5958 if(zmeqto(v,l2zm(4L))||zmeqto(v,l2zm(8L))||zmeqto(v,l2zm(256L))||zmeqto(v,l2zm(512L)))
5959 return 1;
5960
5961 return 0;
5962}
5963
5964static int is_single_eff_ic(struct IC *p)
5965{
5966 struct Var *v,*idx;
5967 if(p->code!=ADDI2P||(p->typf2&NQ)!=POINTER)
5968 return 0;
5969 if(!(p->q2.flags&KONST)){
5970 if((p->typf&NU)!=(UNSIGNED|CHAR))
5971 return 0;
5972 if((p->q2.flags&(VAR|DREFOBJ))!=VAR)
5973 return 0;
5974 if(p->q2.v->storage_class!=AUTO&&p->q2.v->storage_class!=REGISTER)
5975 return 0;
5976 idx=p->q2.v;
5977 }else{
5978 idx=0;
5979 eval_const(&p->q2.val,p->typf);
5980 /* TODO: more precise check considering data type useful? */
5981 if(!zmleq(vumax,l2zm(255L)))
5982 return 0;
5983 return 1;
5984 }
5985 if(p->q1.flags&DREFOBJ)
5986 return 0;
5987 if((p->z.flags&(VAR|DREFOBJ))!=VAR)
5988 return 0;
5989 if(p->z.v->storage_class==STATIC||p->z.v->storage_class==EXTERN)
5990 return 0;
5991 v=p->z.v;
5992 for(p=p->next;p;p=p->next){
5993 int c=p->code;
5994 if(c==LABEL||(c>=BEQ&&c<=BRA))
5995 return 1; /* TODO: how elaborate should we test? */
5996 if((p->q1.flags&VAR)&&p->q1.v==v){
5997 if(p->q1.flags&DREFOBJ)
5998 return 1;
5999 else
6000 return 0;
6001 }
6002 if((p->q2.flags&VAR)&&p->q2.v==v){
6003 if(p->q2.flags&DREFOBJ)
6004 return 1;
6005 else
6006 return 0;
6007 }
6008 if((p->z.flags&VAR)&&p->z.v==v){
6009 if(p->z.flags&DREFOBJ)
6010 return 1;
6011 else
6012 return 0;
6013 }
6014 if((p->z.flags&VAR)&&p->z.v==idx)
6015 return 0;
6016 }
6017 return 0;
6018}
6019
6020void mark_eff_ics(void)
6021{
6022 struct IC *p;
6023 for(p=first_ic;p;p=p->next){
6024 if(is_single_eff_ic(p))
6025 p->flags|=EFF_IC;
6026 else
6027 p->flags&=~EFF_IC;
6028 }
6029}