Rev 7545 | Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6446 | GerdtR | 1 | #define _TOKB_ |
2 | |||
3 | |||
4 | |||
5 | |||
6 | |||
7 | char BXandFS[]="BX and FS"; |
||
8 | |||
9 | int optnumber=FALSE; |
||
10 | |||
11 | char *pbuf; |
||
12 | |||
13 | |||
14 | |||
15 | unsigned int numfloatconst=0; |
||
16 | |||
17 | #define STEPFLOATCONST 16 |
||
18 | |||
19 | unsigned char idxregs[5]={ESI,EDI,EBX,EDX,255}; |
||
20 | |||
21 | int expandvar(); |
||
22 | |||
23 | int leamul32(unsigned long num,int reg,int razr); |
||
24 | |||
25 | |||
26 | |||
27 | void do_e_axmath2(int sign,int razr,int expand); |
||
28 | |||
29 | void DivMod(int vop,int sign,int razr,int expand); |
||
30 | |||
31 | void DivNum(unsigned long num,int razr,int sign); |
||
32 | |||
33 | void doalmath2(int sign); |
||
34 | |||
35 | void reg2bits(ITOK *gtok,int razr); |
||
36 | |||
37 | int CheckAddOnly(); |
||
38 | |||
39 | |||
40 | |||
41 | void intinstack(int addop); |
||
42 | |||
43 | extern void warningoptnum(); |
||
44 | |||
45 | extern void segbyteerror(); |
||
46 | |||
47 | extern void begmathoperror(); |
||
48 | |||
49 | extern void regbyteerror(); |
||
50 | |||
51 | extern void regshifterror(); |
||
52 | |||
53 | extern void DevideZero(); |
||
54 | |||
55 | |||
56 | |||
57 | 0x800,0x1000,0x2000,0x4000,0x8000,0x10000,0x20000,0x40000,0x80000,0x100000, |
||
58 | |||
59 | 0x20000000,0x40000000,0x80000000,0x100000000LL,0x200000000LL,0x400000000LL |
||
60 | |||
61 | ,0x10000000000LL,0x20000000000LL,0x40000000000LL,0x80000000000LL |
||
62 | |||
63 | ,0x1000000000000LL,0x2000000000000LL,0x4000000000000LL,0x8000000000000LL |
||
64 | |||
65 | ,0x100000000000000LL,0x200000000000000LL,0x400000000000000LL,0x800000000000000LL |
||
66 | |||
67 | |||
68 | |||
69 | 375,675,1215,2187,625,1125,2025,3645,6561}; |
||
70 | |||
71 | unsigned int numleamul[24][4]={ |
||
72 | |||
73 | {9,9,0,0},{5,5,3,0},{5,5,5,0},{9,5,3,0},{9,5,5,0},{9,9,3,0},{9,9,5,0}, |
||
74 | |||
75 | {9,9,5,5},{9,9,9,5},{9,9,9,9}}; |
||
76 | |||
77 | int RmEqualReg(int reg,int rm,int sib) |
||
78 | |||
79 | int rm0; |
||
80 | |||
81 | rm0=rm&0x7; |
||
82 | |||
83 | |||
84 | |||
85 | reg1=BX; |
||
86 | |||
87 | break; |
||
88 | |||
89 | reg1=BX; |
||
90 | |||
91 | break; |
||
92 | |||
93 | reg1=BP; |
||
94 | |||
95 | break; |
||
96 | |||
97 | reg1=BP; |
||
98 | |||
99 | break; |
||
100 | |||
101 | reg1=SI; |
||
102 | |||
103 | case 5: |
||
104 | |||
105 | break; |
||
106 | |||
107 | if((rm&0xC0)!=0)reg1=BP; |
||
108 | |||
109 | |||
110 | |||
111 | break; |
||
112 | |||
113 | } |
||
114 | |||
115 | if(rm0==4){ |
||
116 | |||
117 | reg2=(sib>>3)&7; |
||
118 | |||
119 | if(reg2==4)reg2=-1; |
||
120 | |||
121 | else{ |
||
122 | |||
123 | if(reg1==5&&(rm&0xc0)==0)reg1=-1; |
||
124 | |||
125 | } |
||
126 | |||
127 | return FALSE; |
||
128 | |||
129 | |||
130 | |||
131 | { |
||
132 | |||
133 | |||
134 | |||
135 | outword(0xD08B); //mov dx,ax |
||
136 | |||
137 | } |
||
138 | |||
139 | |||
140 | |||
141 | { |
||
142 | |||
143 | if(num==1)outword(0xC002); //add al,al |
||
144 | |||
145 | if(chip==0){ |
||
146 | |||
147 | op(num); |
||
148 | |||
149 | warningreg(begs[1]); |
||
150 | |||
151 | |||
152 | |||
153 | op(num); |
||
154 | |||
155 | } |
||
156 | |||
157 | else{ |
||
158 | |||
159 | op66(razr); |
||
160 | |||
161 | op(0xC0+reg*9); //add reg,reg |
||
162 | |||
163 | else{ |
||
164 | |||
165 | op(0xB1); //mov cl,num |
||
166 | |||
167 | op(0xD3); |
||
168 | |||
169 | warningreg(begs[1]); |
||
170 | |||
171 | else{ |
||
172 | |||
173 | op66(razr); |
||
174 | |||
175 | op(0xE0+reg); //shl ax,num |
||
176 | |||
177 | } |
||
178 | |||
179 | } |
||
180 | |||
181 | |||
182 | |||
183 | { |
||
184 | |||
185 | else{ |
||
186 | |||
187 | outword(0xC22B); //sub ax,dx |
||
188 | |||
189 | } |
||
190 | |||
191 | void addmul(int razr) |
||
192 | |||
193 | if(razr==r8)outword(0xC402); //add al,ah |
||
194 | |||
195 | op66(razr); |
||
196 | |||
197 | } |
||
198 | |||
199 | |||
200 | |||
201 | { |
||
202 | |||
203 | int vop=0,i=8*reg+4; |
||
204 | |||
205 | case 9: vop+=0x40; |
||
206 | |||
207 | case 3: vop+=0x40; |
||
208 | |||
209 | op67(r32); // AX * n = LEA AX,[EAX*n+?EAX] |
||
210 | |||
211 | op(reg==BP?i|rm_mod01:i); |
||
212 | |||
213 | if(reg==BP)op(0); |
||
214 | |||
215 | } |
||
216 | |||
217 | switch(num){ |
||
218 | |||
219 | case 4: vop=0x85; break; |
||
220 | |||
221 | default: return FALSE; |
||
222 | |||
223 | op66(razr); |
||
224 | |||
225 | op(0x8d); |
||
226 | |||
227 | op(i); |
||
228 | |||
229 | if(vop==0x85||vop==0xc5)outdword(0L); |
||
230 | |||
231 | return TRUE; |
||
232 | |||
233 | |||
234 | |||
235 | { |
||
236 | |||
237 | for(i=3;i<24;i++){ |
||
238 | |||
239 | leamul32(numleamul[i][0],reg,razr); |
||
240 | |||
241 | leamul32(numleamul[i][2],reg,razr); |
||
242 | |||
243 | return TRUE; |
||
244 | |||
245 | } |
||
246 | |||
247 | unsigned long v=li[j]; |
||
248 | |||
249 | for(i=0;i<15;i++){ |
||
250 | |||
251 | if(lm==num){ |
||
252 | |||
253 | lshiftmul(j,razr,reg); |
||
254 | |||
255 | leamul32(numleamul[i][2],reg,razr); |
||
256 | |||
257 | |||
258 | |||
259 | } |
||
260 | |||
261 | return FALSE; |
||
262 | |||
263 | |||
264 | |||
265 | //сдвиги и сложения |
||
266 | |||
267 | int first,second; |
||
268 | |||
269 | unsigned long v=li[j]; |
||
270 | |||
271 | if((num%(v-1))==0){ |
||
272 | |||
273 | if(second!=NUMNUM){ |
||
274 | |||
275 | if(first!=1){ |
||
276 | |||
277 | |||
278 | |||
279 | if(second!=0)lshiftmul(second,razr); |
||
280 | |||
281 | return TRUE; |
||
282 | |||
283 | } |
||
284 | |||
285 | if((v+1)>num)break; |
||
286 | |||
287 | second=caselong(num/(v+1)); |
||
288 | |||
289 | first=caselong(v); |
||
290 | |||
291 | lshiftmul(first,razr); |
||
292 | |||
293 | if(second!=0)lshiftmul(second,razr); |
||
294 | |||
295 | return TRUE; |
||
296 | |||
297 | } |
||
298 | |||
299 | if((v-1)>(num-1))break; |
||
300 | |||
301 | second=caselong((num-1)/(v-1)); |
||
302 | |||
303 | first=caselong(v); |
||
304 | |||
305 | startmul(razr); |
||
306 | |||
307 | submul(razr); |
||
308 | |||
309 | addmul(razr); |
||
310 | |||
311 | return TRUE; |
||
312 | |||
313 | } |
||
314 | |||
315 | if((v+1)>(num-1))break; |
||
316 | |||
317 | second=caselong((num-1)/(v+1)); |
||
318 | |||
319 | first=caselong(v); |
||
320 | |||
321 | lshiftmul(first,razr); |
||
322 | |||
323 | lshiftmul(second,razr); |
||
324 | |||
325 | setzeroflag=TRUE; |
||
326 | |||
327 | } |
||
328 | |||
329 | if((v-1)>(num+1))break; |
||
330 | |||
331 | second=caselong((num+1)/(v-1)); |
||
332 | |||
333 | first=caselong(v); |
||
334 | |||
335 | startmul(razr); |
||
336 | |||
337 | submul(razr); |
||
338 | |||
339 | submul(razr); |
||
340 | |||
341 | return TRUE; |
||
342 | |||
343 | } |
||
344 | |||
345 | if((v+1)>(num+1))break; |
||
346 | |||
347 | second=caselong((num+1)/(v+1)); |
||
348 | |||
349 | first=caselong(v); |
||
350 | |||
351 | lshiftmul(first,razr); |
||
352 | |||
353 | lshiftmul(second,razr); |
||
354 | |||
355 | setzeroflag=TRUE; |
||
356 | |||
357 | } |
||
358 | |||
359 | } |
||
360 | |||
361 | |||
362 | |||
363 | |||
364 | |||
365 | unsigned int *rflag,ITOK *posttok) |
||
366 | |||
367 | // printf("in:reg=%02X base=%02X idx=%02X zoom=%02X\n",reg,*base,*idx,*zoom); |
||
368 | |||
369 | // printf("tok=%d flag=%08X %s\n",tok2,itok2.flag,itok2.name); |
||
370 | |||
371 | if((tok==tk_plus||tok==tk_minus)&&(tok2==tk_minus|| |
||
372 | |||
373 | (tok2==tk_postnumber&&posttok->post==0)||(tok==tk_plus&&tok2==tk_rmnumber&&(itok2.flag&f_useidx)==0))){ |
||
374 | |||
375 | } |
||
376 | |||
377 | ||(tok2!=tk_reg32&&tok2!=tk_number)||tok2==tk_rmnumber){ |
||
378 | |||
379 | |||
380 | |||
381 | break; |
||
382 | |||
383 | if(tok==tk_mult&&(tok2!=tk_number||*zoom!=-1||*val!=0||*idx!=-1))break; |
||
384 | |||
385 | if(tok==tk_minus){ |
||
386 | |||
387 | nexttok(); |
||
388 | |||
389 | if(tok2!=tk_number)break; |
||
390 | |||
391 | *val+=itok.number; |
||
392 | |||
393 | else *val-=itok.number; |
||
394 | |||
395 | else *posttok=itok; |
||
396 | |||
397 | |||
398 | |||
399 | if(tok==tk_number){ |
||
400 | |||
401 | *rflag^=itok.flag; |
||
402 | |||
403 | else if(tok==tk_postnumber){ |
||
404 | |||
405 | *posttok=itok; |
||
406 | |||
407 | else if(tok==tk_rmnumber){ |
||
408 | |||
409 | ExpandRm(itok.rm,itok.sib,&z,&r1,&r2); |
||
410 | |||
411 | if(r1>=0&&r2>=0&&(*idx>=0||*base>=0))break; |
||
412 | |||
413 | if(*zoom<=0)*zoom=z; |
||
414 | |||
415 | if(r1>=0){ |
||
416 | |||
417 | r1=-1; |
||
418 | |||
419 | else{ |
||
420 | |||
421 | r2=-1; |
||
422 | |||
423 | } |
||
424 | |||
425 | if(r1>=0)*idx=r1; |
||
426 | |||
427 | } |
||
428 | |||
429 | else{ |
||
430 | |||
431 | else *idx=itok.number; |
||
432 | |||
433 | } |
||
434 | |||
435 | *zoom=0; |
||
436 | |||
437 | case 8: *zoom=*zoom+1; |
||
438 | |||
439 | case 2: *zoom=*zoom+1; |
||
440 | |||
441 | *idx=*base; |
||
442 | |||
443 | break; |
||
444 | |||
445 | case 5: *zoom=*zoom+1; |
||
446 | |||
447 | *zoom=*zoom+1; |
||
448 | |||
449 | break; |
||
450 | |||
451 | } |
||
452 | |||
453 | nexttok(); |
||
454 | |||
455 | else break; |
||
456 | |||
457 | if(*base!=-1&&*idx!=-1&&tok2!=tk_number)break; |
||
458 | |||
459 | if(*zoom==-1&&*base==-1){ |
||
460 | |||
461 | *idx=-1; |
||
462 | |||
463 | // printf("out:reg=%02X base=%02X idx=%02X zoom=%02X\n",reg,*base,*idx,*zoom); |
||
464 | |||
465 | |||
466 | |||
467 | unsigned int rflag,ITOK *posttok) |
||
468 | |||
469 | int mod=rm_mod00; |
||
470 | |||
471 | if(zoom==-1)zoom=0; |
||
472 | |||
473 | if(short_ok(val,TRUE)!=0)mod=rm_mod01; |
||
474 | |||
475 | } |
||
476 | |||
477 | if(idx==-1){ |
||
478 | |||
479 | base=-1; |
||
480 | |||
481 | if(base==-1){ |
||
482 | |||
483 | op66(r32); |
||
484 | |||
485 | op(0x8d); |
||
486 | |||
487 | op((reg*8+idx)|mod); |
||
488 | |||
489 | } |
||
490 | |||
491 | if(idx==4)return FALSE; |
||
492 | |||
493 | op66(r32); |
||
494 | |||
495 | op(0x8d); |
||
496 | |||
497 | op(idx*8+5+(zoom<<6)); |
||
498 | |||
499 | } |
||
500 | |||
501 | if(idx==4){ |
||
502 | |||
503 | else if(zoom==0){ |
||
504 | |||
505 | base=idx; |
||
506 | |||
507 | } |
||
508 | |||
509 | } |
||
510 | |||
511 | if(idx!=-1&&idx!=5){ |
||
512 | |||
513 | q=base; |
||
514 | |||
515 | idx=q; |
||
516 | |||
517 | else mod=rm_mod01; |
||
518 | |||
519 | else mod=rm_mod01; |
||
520 | |||
521 | op66(r32); |
||
522 | |||
523 | op(0x8d); |
||
524 | |||
525 | |||
526 | |||
527 | if(mod==rm_mod01)op(val); |
||
528 | |||
529 | if(posttok->post)setwordpost(posttok); |
||
530 | |||
531 | outdword(val); |
||
532 | |||
533 | else if(mod==rm_mod00&&base==5)outdword(val); |
||
534 | |||
535 | } |
||
536 | |||
537 | int Reg32ToLea2(int reg) //оптимизация сложения 32-битных регистров в LEA |
||
538 | |||
539 | int idx,base,zoom; |
||
540 | |||
541 | int otok,otok2,otype2; |
||
542 | |||
543 | unsigned int oinptr,rflag; |
||
544 | |||
545 | ITOK oitok; |
||
546 | |||
547 | if(tok!=tk_minus&&tok!=tk_plus&&tok!=tk_mult)return FALSE; |
||
548 | |||
549 | if(tok==tk_mult&&(!(tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_double&&(itok2.flag&f_reloc)==0)))return FALSE; |
||
550 | |||
551 | if(cur_mod)return FALSE; |
||
552 | |||
553 | idx=zoom=-1; |
||
554 | |||
555 | if(tok==tk_mult){ |
||
556 | |||
557 | switch(itok2.number){ |
||
558 | |||
559 | case 4: zoom++; |
||
560 | |||
561 | case 1: |
||
562 | |||
563 | base=-1; |
||
564 | |||
565 | //new! |
||
566 | |||
567 | case 5: zoom++; |
||
568 | |||
569 | // if(!(am32==FALSE&&tok!=tk_plus&&(!(tok2==tk_minus||tok2==tk_number)))){ |
||
570 | |||
571 | zoom++; |
||
572 | |||
573 | break; |
||
574 | |||
575 | // end new!! |
||
576 | |||
577 | } |
||
578 | |||
579 | zoom=-1; |
||
580 | |||
581 | idx=-1; |
||
582 | |||
583 | } |
||
584 | |||
585 | rflag=0; |
||
586 | |||
587 | ocha=cha2; |
||
588 | |||
589 | oitok=itok; |
||
590 | |||
591 | otype2=itok2.type; |
||
592 | |||
593 | if(tok==tk_mult){ |
||
594 | |||
595 | nexttok(); |
||
596 | |||
597 | CheckRegForLea(reg,&idx,&base,&zoom,&val,&rflag,&posttok); |
||
598 | |||
599 | if(idx==-1)next=1; |
||
600 | |||
601 | if(zoom==-1)next|=4; |
||
602 | |||
603 | // printf("next=%d\n",next); |
||
604 | |||
605 | case 1: // idx=-1 Rb+N |
||
606 | |||
607 | case 4: // zoom=-1 Rb+Ri+N |
||
608 | |||
609 | break; |
||
610 | |||
611 | if(zoom<3){ |
||
612 | |||
613 | if(val<128)goto retfalse; |
||
614 | |||
615 | } |
||
616 | |||
617 | } |
||
618 | |||
619 | case 8: // val=0 Rb+Ri*Z |
||
620 | |||
621 | default: |
||
622 | |||
623 | // case 10: // val=0 base=-1 Ri*Z |
||
624 | |||
625 | // case 5: // idx=-1 zoom=-1 Rb+N |
||
626 | |||
627 | // case 6: // base=-1 zoom=-1 Ri+N |
||
628 | |||
629 | // case 9: // val=0 idx=-1 Rb |
||
630 | |||
631 | // case 7: // idx=-1 base=-1 zoom=-1 N |
||
632 | |||
633 | retfalse: |
||
634 | |||
635 | cha2=ocha; |
||
636 | |||
637 | itok=oitok; |
||
638 | |||
639 | itok2.type=(unsigned short)otype2; |
||
640 | |||
641 | free(bufrm); |
||
642 | |||
643 | } |
||
644 | |||
645 | free(strinf.bufstr); |
||
646 | |||
647 | } |
||
648 | |||
649 | linenum2=linenumber=oline; |
||
650 | |||
651 | } |
||
652 | |||
653 | ClearReg(reg); |
||
654 | |||
655 | return TRUE; |
||
656 | |||
657 | |||
658 | |||
659 | { |
||
660 | |||
661 | unsigned long val; |
||
662 | |||
663 | unsigned char ocha,next; |
||
664 | |||
665 | ITOK oitok; |
||
666 | |||
667 | ITOK posttok; |
||
668 | |||
669 | oinptr=inptr2; |
||
670 | |||
671 | otok=tok; |
||
672 | |||
673 | otok2=tok2; |
||
674 | |||
675 | base=idx=zoom=-1; |
||
676 | |||
677 | rflag=0; |
||
678 | |||
679 | tok=tk_plus; |
||
680 | |||
681 | if(tok!=tk_semicolon)goto retfalse; |
||
682 | |||
683 | else if(idx==-1)idx=reg; |
||
684 | |||
685 | next=0; |
||
686 | |||
687 | if(base==-1)next|=2; |
||
688 | |||
689 | if(val==0&&rflag==0&&posttok.post==0)next|=8; |
||
690 | |||
691 | if(val==0&&rflag==0&&posttok.post==0)next|=8; |
||
692 | |||
693 | case 5: // idx=-1 zoom=-1 Rb+N |
||
694 | |||
695 | if(val<3||val>0xfffffffd)goto retfalse; |
||
696 | |||
697 | break; |
||
698 | |||
699 | if(val==1||val==0xffffffff)goto retfalse; |
||
700 | |||
701 | case 0: |
||
702 | |||
703 | break; |
||
704 | |||
705 | // case 13: // val=0 idx=-1 zoom=-1 Rb |
||
706 | |||
707 | // case 6: // base=-1 zoom=-1 Ri+N |
||
708 | |||
709 | // case 9: // val=0 idx=-1 Rb |
||
710 | |||
711 | // case 7: // idx=-1 base=-1 zoom=-1 N |
||
712 | |||
713 | retfalse: |
||
714 | |||
715 | cha2=ocha; |
||
716 | |||
717 | itok=oitok; |
||
718 | |||
719 | itok2=oitok2; |
||
720 | |||
721 | if(bufrm){ |
||
722 | |||
723 | bufrm=NULL; |
||
724 | |||
725 | |||
726 | |||
727 | strinf.bufstr=NULL; |
||
728 | |||
729 | // printf("return input=%08X inptr=%08X\n",input,inptr2); |
||
730 | |||
731 | } |
||
732 | |||
733 | if(OutLea(reg,idx,base,zoom,val,rflag,&posttok)==FALSE)goto retfalse; |
||
734 | |||
735 | } |
||
736 | |||
737 | int Reg32ToLea(int reg) //оптимизация сложения 32-битных регистров в LEA |
||
738 | |||
739 | int idx,base,zoom; |
||
740 | |||
741 | int otok,otok2,otype2; |
||
742 | |||
743 | unsigned int oinptr,rflag; |
||
744 | |||
745 | ITOK oitok; |
||
746 | |||
747 | if(tok!=tk_reg32&&tok!=tk_number&&tok!=tk_postnumber&&(!(tok==tk_rmnumber&&(itok.flag&f_useidx)==0)))return FALSE; |
||
748 | |||
749 | posttok.post=0; |
||
750 | |||
751 | val=0; |
||
752 | |||
753 | // printf("input=%08X inptr=%08X\n",input,inptr2); |
||
754 | |||
755 | ocha=cha2; |
||
756 | |||
757 | oitok=itok; |
||
758 | |||
759 | otype2=itok2.type; |
||
760 | |||
761 | // printf("tok=%d type=%d %s\n",tok,itok.type,itok.name); |
||
762 | |||
763 | if(itok.rm==tk_float||itok.rm==tk_double||itok.rm==tk_qword)return FALSE; |
||
764 | |||
765 | rflag=postnumflag; |
||
766 | |||
767 | } |
||
768 | |||
769 | posttok=itok; |
||
770 | |||
771 | val=doconstdwordmath(); |
||
772 | |||
773 | } |
||
774 | |||
775 | ExpandRm(itok.rm,itok.sib,&zoom,&base,&idx); |
||
776 | |||
777 | nexttok(); |
||
778 | |||
779 | else{ |
||
780 | |||
781 | nexttok(); |
||
782 | |||
783 | if(tok==tk_mult){ |
||
784 | |||
785 | if(base==-1&&tok==tk_reg32){ |
||
786 | |||
787 | idx=itok.number; |
||
788 | |||
789 | else if(base!=-1&&tok==tk_number){ |
||
790 | |||
791 | idx=base; |
||
792 | |||
793 | val=itok.number; |
||
794 | |||
795 | else goto retfalse; |
||
796 | |||
797 | zoom=0; |
||
798 | |||
799 | case 8: zoom++; |
||
800 | |||
801 | case 2: zoom++; |
||
802 | |||
803 | //new! |
||
804 | |||
805 | case 5: zoom++; |
||
806 | |||
807 | // if(!(am32==FALSE&&tok!=tk_plus&&(!(tok2==tk_minus||tok2==tk_number)))){ |
||
808 | |||
809 | zoom++; |
||
810 | |||
811 | break; |
||
812 | |||
813 | // end new!! |
||
814 | |||
815 | goto retfalse; |
||
816 | |||
817 | if(zoom==0){ |
||
818 | |||
819 | base=idx; |
||
820 | |||
821 | } |
||
822 | |||
823 | } |
||
824 | |||
825 | next=0; |
||
826 | |||
827 | if(base==-1)next|=2; |
||
828 | |||
829 | if(val==0&&rflag==0&&posttok.post==0)next|=8; |
||
830 | |||
831 | case 5: // idx=-1 zoom=-1 Rb+N |
||
832 | |||
833 | if(base==ESP&&val==1)goto retfalse; |
||
834 | |||
835 | if(base==reg)goto retfalse; |
||
836 | |||
837 | case 10: // val=0 base=-1 Ri*Z |
||
838 | |||
839 | break; |
||
840 | |||
841 | if(optimizespeed)break; |
||
842 | |||
843 | if(zoom==2&&val>2){ |
||
844 | |||
845 | if(idx!=reg)break; |
||
846 | |||
847 | } |
||
848 | |||
849 | } |
||
850 | |||
851 | goto retfalse; |
||
852 | |||
853 | case 0: |
||
854 | |||
855 | case 8: // val=0 Rb+Ri*Z |
||
856 | |||
857 | default: |
||
858 | |||
859 | // case 3: // idx=-1 base=-1 N |
||
860 | |||
861 | // case 11: // val=0 base=-1 idx=-1 - |
||
862 | |||
863 | // case 14: // val=0 base=-1 zoom=-1 Ri |
||
864 | |||
865 | // case 15: // val=0 base=-1 idx=-1 zoom=-1 |
||
866 | |||
867 | inptr2=oinptr; |
||
868 | |||
869 | tok=otok; |
||
870 | |||
871 | tok2=otok2; |
||
872 | |||
873 | linenum2=linenumber=oline; |
||
874 | |||
875 | if(bufrm){ |
||
876 | |||
877 | bufrm=NULL; |
||
878 | |||
879 | if(strinf.bufstr){ |
||
880 | |||
881 | strinf.bufstr=NULL; |
||
882 | |||
883 | // printf("return input=%08X inptr=%08X\n",input,inptr2); |
||
884 | |||
885 | } |
||
886 | |||
887 | if(OutLea(reg,idx,base,zoom,val,rflag,&posttok)==FALSE)goto retfalse; |
||
888 | |||
889 | return TRUE; |
||
890 | |||
891 | |||
892 | |||
893 | { |
||
894 | |||
895 | for(;;){ |
||
896 | |||
897 | if(tok2==tk_postnumber&&(posttok->post||tok==tk_minus))break; |
||
898 | |||
899 | if(itok2.number==reg)endloop=TRUE; |
||
900 | |||
901 | switch(itok2.number){ |
||
902 | |||
903 | case BP: |
||
904 | |||
905 | case DI: |
||
906 | |||
907 | break; |
||
908 | |||
909 | } |
||
910 | |||
911 | else if(*idx==-1){ |
||
912 | |||
913 | case BX: |
||
914 | |||
915 | if(*base==BX||*base==BP)endloop=TRUE; |
||
916 | |||
917 | *idx=*base; |
||
918 | |||
919 | } |
||
920 | |||
921 | case SI: |
||
922 | |||
923 | if(*base==SI||*base==DI)endloop=TRUE; |
||
924 | |||
925 | *idx=itok2.number; |
||
926 | |||
927 | break; |
||
928 | |||
929 | |||
930 | |||
931 | else break; |
||
932 | |||
933 | nexttok(); |
||
934 | |||
935 | else if(tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_qword&&itok2.rm!=tk_double){ |
||
936 | |||
937 | else *val-=itok2.number; |
||
938 | |||
939 | *rflag^=itok.flag; |
||
940 | |||
941 | else if(tok2==tk_postnumber){ |
||
942 | |||
943 | if(tok==tk_plus)*val+=itok2.number; |
||
944 | |||
945 | nexttok(); |
||
946 | |||
947 | } |
||
948 | |||
949 | nexttok(); |
||
950 | |||
951 | } |
||
952 | |||
953 | void OutLea16(int reg,int idx,int base,unsigned int val,int rflag,ITOK *posttok) |
||
954 | |||
955 | int mod=rm_mod00; |
||
956 | |||
957 | if(val!=0){ |
||
958 | |||
959 | else mod=rm_mod10; |
||
960 | |||
961 | if((rflag&f_reloc)!=0||posttok->post)mod=rm_mod10; |
||
962 | |||
963 | op66(r16); |
||
964 | |||
965 | op(0x8D); |
||
966 | |||
967 | if(mod==rm_mod01)op(val); |
||
968 | |||
969 | if(posttok->post)setwordpost(posttok); |
||
970 | |||
971 | outword(val); |
||
972 | |||
973 | } |
||
974 | |||
975 | int Reg16ToLea(int reg) //оптимизация сложения 16-битных регистров в LEA |
||
976 | |||
977 | int idx,base; |
||
978 | |||
979 | int otok,otok2,otype2; |
||
980 | |||
981 | unsigned int oinptr,rflag; |
||
982 | |||
983 | ITOK oitok; |
||
984 | |||
985 | if(cur_mod)return FALSE; |
||
986 | |||
987 | // if(tok!=tk_reg&&tok!=tk_number&&am32!=0&&tok2!=tk_plus)return FALSE; |
||
988 | |||
989 | idx=base=-1; |
||
990 | |||
991 | if(itok.number==reg)return FALSE; |
||
992 | |||
993 | case BX: |
||
994 | |||
995 | case SI: |
||
996 | |||
997 | base=itok.number; |
||
998 | |||
999 | default: return FALSE; |
||
1000 | |||
1001 | } |
||
1002 | |||
1003 | rflag=0; |
||
1004 | |||
1005 | ocha=cha2; |
||
1006 | |||
1007 | oitok=itok; |
||
1008 | |||
1009 | otype2=itok2.type; |
||
1010 | |||
1011 | if(tok==tk_postnumber){ |
||
1012 | |||
1013 | tok=tk_number; |
||
1014 | |||
1015 | if(tok==tk_number){ |
||
1016 | |||
1017 | rflag=postnumflag; |
||
1018 | |||
1019 | else nexttok(); |
||
1020 | |||
1021 | next=0; |
||
1022 | |||
1023 | if(base==-1)next|=2; |
||
1024 | |||
1025 | switch(next){ |
||
1026 | |||
1027 | case 1: //base+num |
||
1028 | |||
1029 | // case 3: //num |
||
1030 | |||
1031 | // case 6: //idx |
||
1032 | |||
1033 | break; |
||
1034 | |||
1035 | if(am32==0)break; |
||
1036 | |||
1037 | retfalse: |
||
1038 | |||
1039 | cha2=ocha; |
||
1040 | |||
1041 | itok=oitok; |
||
1042 | |||
1043 | itok2.type=(unsigned short)otype2; |
||
1044 | |||
1045 | endoffile=0; |
||
1046 | |||
1047 | free(bufrm); |
||
1048 | |||
1049 | } |
||
1050 | |||
1051 | free(strinf.bufstr); |
||
1052 | |||
1053 | } |
||
1054 | |||
1055 | } |
||
1056 | |||
1057 | return TRUE; |
||
1058 | |||
1059 | |||
1060 | |||
1061 | { |
||
1062 | |||
1063 | unsigned long val; |
||
1064 | |||
1065 | unsigned char ocha,next; |
||
1066 | |||
1067 | int oline; |
||
1068 | |||
1069 | ITOK posttok; |
||
1070 | |||
1071 | |||
1072 | |||
1073 | (reg==BX||reg==BP||reg==SI||reg==DI)){ |
||
1074 | |||
1075 | rflag=0; |
||
1076 | |||
1077 | ocha=cha2; |
||
1078 | |||
1079 | oitok=itok; |
||
1080 | |||
1081 | otype2=itok2.type; |
||
1082 | |||
1083 | idx=-1; |
||
1084 | |||
1085 | CheckRegForLea16(reg,&idx,&base,&val,&rflag,&posttok); |
||
1086 | |||
1087 | if(idx==-1)next=1; |
||
1088 | |||
1089 | if(val==0&&rflag==0&&posttok.post==0)next|=4; |
||
1090 | |||
1091 | case 1: //base+num |
||
1092 | |||
1093 | case 0: //base+idx+num |
||
1094 | |||
1095 | // case 3: //num |
||
1096 | |||
1097 | // case 6: //idx |
||
1098 | |||
1099 | break; |
||
1100 | |||
1101 | default: |
||
1102 | |||
1103 | inptr2=oinptr; |
||
1104 | |||
1105 | tok=otok; |
||
1106 | |||
1107 | tok2=otok2; |
||
1108 | |||
1109 | endoffile=0; |
||
1110 | |||
1111 | if(bufrm){ |
||
1112 | |||
1113 | bufrm=NULL; |
||
1114 | |||
1115 | if(strinf.bufstr){ |
||
1116 | |||
1117 | strinf.bufstr=NULL; |
||
1118 | |||
1119 | return FALSE; |
||
1120 | |||
1121 | OutLea16(reg,idx,base,val,rflag,&posttok); |
||
1122 | |||
1123 | } |
||
1124 | |||
1125 | } |
||
1126 | |||
1127 | int OptimNum() //оптимизация цифровых операндов |
||
1128 | |||
1129 | int otok,oinptr,deistv,negflag,starttok; |
||
1130 | |||
1131 | long long val; |
||
1132 | |||
1133 | int plusreloc=0; |
||
1134 | |||
1135 | if(tok==tk_minus&&(itok2.flag&f_reloc))return FALSE; |
||
1136 | |||
1137 | negflag=0; |
||
1138 | |||
1139 | oflag=itok.flag; |
||
1140 | |||
1141 | ocha2=cha2; |
||
1142 | |||
1143 | flag=itok.flag; |
||
1144 | |||
1145 | switch(otok){ |
||
1146 | |||
1147 | val=-val; |
||
1148 | |||
1149 | for(;;){ //оптимизация сложений-вычитаний |
||
1150 | |||
1151 | if((tok!=tk_plus&&tok!=tk_minus)||tok2!=tk_number|| |
||
1152 | |||
1153 | tok=otok; |
||
1154 | |||
1155 | inptr2=oinptr; |
||
1156 | |||
1157 | if(deistv==0)break; //ничего не было оптимизировано |
||
1158 | |||
1159 | tok=tk_plus; |
||
1160 | |||
1161 | itok.flag|=flag; |
||
1162 | |||
1163 | } |
||
1164 | |||
1165 | nexttok(); |
||
1166 | |||
1167 | ocha2=cha2; |
||
1168 | |||
1169 | val-=itok.lnumber; |
||
1170 | |||
1171 | } |
||
1172 | |||
1173 | val+=itok.lnumber; |
||
1174 | |||
1175 | } |
||
1176 | |||
1177 | } |
||
1178 | |||
1179 | case tk_divminus: |
||
1180 | |||
1181 | goto LL1; |
||
1182 | |||
1183 | otok=tk_mult; |
||
1184 | |||
1185 | negflag=TRUE; |
||
1186 | |||
1187 | case tk_mult: |
||
1188 | |||
1189 | nexttok(); |
||
1190 | |||
1191 | tok2!=tk_number|| |
||
1192 | |||
1193 | ||(val |
||
1194 | |||
1195 | tok=starttok; |
||
1196 | |||
1197 | inptr2=oinptr; |
||
1198 | |||
1199 | if(deistv==0)break; |
||
1200 | |||
1201 | tok=otok; |
||
1202 | |||
1203 | itok.lnumber=val; |
||
1204 | |||
1205 | return TRUE; |
||
1206 | |||
1207 | if(tok==tk_divminus){ |
||
1208 | |||
1209 | negflag^=TRUE; |
||
1210 | |||
1211 | else if(tok==tk_multminus){ |
||
1212 | |||
1213 | negflag^=TRUE; |
||
1214 | |||
1215 | deistv=tok; |
||
1216 | |||
1217 | oinptr=inptr2; |
||
1218 | |||
1219 | if(otok==deistv)val=val*itok.lnumber; |
||
1220 | |||
1221 | if(val>itok.lnumber)val=val/itok.lnumber; |
||
1222 | |||
1223 | val=itok.lnumber/val; |
||
1224 | |||
1225 | } |
||
1226 | |||
1227 | val=1; |
||
1228 | |||
1229 | } |
||
1230 | |||
1231 | flag|=itok.flag; |
||
1232 | |||
1233 | break; |
||
1234 | |||
1235 | tok=starttok; |
||
1236 | |||
1237 | inptr2=oinptr; |
||
1238 | |||
1239 | } |
||
1240 | |||
1241 | free(bufrm); |
||
1242 | |||
1243 | } |
||
1244 | |||
1245 | free(strinf.bufstr); |
||
1246 | |||
1247 | } |
||
1248 | |||
1249 | } |
||
1250 | |||
1251 | int expandvar() |
||
1252 | |||
1253 | if(divexpand==FALSE)return FALSE; |
||
1254 | |||
1255 | switch(input[i]){ |
||
1256 | |||
1257 | case ';': |
||
1258 | |||
1259 | case '|': |
||
1260 | |||
1261 | case ',': |
||
1262 | |||
1263 | case '&': return FALSE; |
||
1264 | |||
1265 | i++; |
||
1266 | |||
1267 | case '%': goto en; |
||
1268 | |||
1269 | } |
||
1270 | |||
1271 | warningexpand(); |
||
1272 | |||
1273 | } |
||
1274 | |||
1275 | void RegMulNum(int reg,unsigned long num,int razr,int sign,int *expand,int flag) |
||
1276 | |||
1277 | int vop,i=0; |
||
1278 | |||
1279 | if(razr==r16)num&=0xffff; |
||
1280 | |||
1281 | setzeroflag=FALSE; |
||
1282 | |||
1283 | } |
||
1284 | |||
1285 | case 0: |
||
1286 | |||
1287 | setzeroflag=TRUE; |
||
1288 | |||
1289 | case 2: /* AX * 2 = ADD AX,AX */ |
||
1290 | |||
1291 | if(optimizespeed==FALSE)goto num_imul; |
||
1292 | |||
1293 | else{ |
||
1294 | |||
1295 | outword(0xD231); |
||
1296 | |||
1297 | } |
||
1298 | |||
1299 | op(1); |
||
1300 | |||
1301 | if(*expand==TRUE){ |
||
1302 | |||
1303 | outword(0xd283); //adc dx,0 |
||
1304 | |||
1305 | ClearReg(DX); |
||
1306 | |||
1307 | setzeroflag=TRUE; |
||
1308 | |||
1309 | default: |
||
1310 | |||
1311 | if(vop!=NUMNUM){ |
||
1312 | |||
1313 | |||
1314 | |||
1315 | op(0xB1); op(vop); /* MOV CL,num */ |
||
1316 | |||
1317 | if(sign)op(0x99); |
||
1318 | |||
1319 | outdword(0xd213c001); //ADD AX,AX ADC DX,DX |
||
1320 | |||
1321 | warningreg(regs[0][2]); |
||
1322 | |||
1323 | } |
||
1324 | |||
1325 | if(reg==CX)goto num_imul; |
||
1326 | |||
1327 | for(;vop!=0;vop--){ |
||
1328 | |||
1329 | op(3); //add |
||
1330 | |||
1331 | } |
||
1332 | |||
1333 | } |
||
1334 | |||
1335 | op(0xD3); |
||
1336 | |||
1337 | } |
||
1338 | |||
1339 | warningreg(begs[1]); |
||
1340 | |||
1341 | else{/* SHL AX,num */ |
||
1342 | |||
1343 | if(optimizespeed==FALSE)goto num_imul; |
||
1344 | |||
1345 | ClearDX(razr,sign); |
||
1346 | |||
1347 | else{ |
||
1348 | |||
1349 | outword(0xC031); |
||
1350 | |||
1351 | if(chip<3&&razr==r16){ |
||
1352 | |||
1353 | outdword(0xd213c001); //ADD AX,AX ADC DX,DX |
||
1354 | |||
1355 | ConstToReg(vop,CL,r8); |
||
1356 | |||
1357 | } |
||
1358 | |||
1359 | op66(razr); |
||
1360 | |||
1361 | outword(0xC2a4); //SHLD DX,AX,num |
||
1362 | |||
1363 | op66(razr); |
||
1364 | |||
1365 | op(vop); |
||
1366 | |||
1367 | ClearReg(DX); |
||
1368 | |||
1369 | } |
||
1370 | |||
1371 | op66(razr); |
||
1372 | |||
1373 | op(0xe0+reg); // SHL reg,imm8 |
||
1374 | |||
1375 | if(cpu<2)cpu=2; |
||
1376 | |||
1377 | } |
||
1378 | |||
1379 | break; |
||
1380 | |||
1381 | if(chip<7&&*expand==FALSE&&optimizespeed&&speedmul32(num,reg,razr))break; |
||
1382 | |||
1383 | if((razr==r16&&chip<2)||(*expand==TRUE)){ |
||
1384 | |||
1385 | op66(razr); |
||
1386 | |||
1387 | if((flag&f_reloc)!=0)AddReloc(); |
||
1388 | |||
1389 | op66(razr); |
||
1390 | |||
1391 | else outword(0xE1F7); /* MUL CX */ |
||
1392 | |||
1393 | warningreg(regs[razr/2-1][1]); |
||
1394 | |||
1395 | else{ |
||
1396 | |||
1397 | op(0x90+reg); //XCHG AX,reg |
||
1398 | |||
1399 | op(reg!=DX?0xBA:0xB9); |
||
1400 | |||
1401 | op66(r16); |
||
1402 | |||
1403 | op(reg!=DX?0xE2:0xE1); // mul DX |
||
1404 | |||
1405 | op(0x90+reg); //XCHG AX,reg |
||
1406 | |||
1407 | ClearReg(DX); |
||
1408 | |||
1409 | } |
||
1410 | |||
1411 | if((flag&f_reloc)==0&&short_ok(num,razr/2-1))i=2; //короткая форма |
||
1412 | |||
1413 | op(0x69+i); //imul |
||
1414 | |||
1415 | if(i==2)op(num); |
||
1416 | |||
1417 | if((flag&f_reloc)!=0)AddReloc(); |
||
1418 | |||
1419 | } |
||
1420 | |||
1421 | setzeroflag=FALSE; |
||
1422 | |||
1423 | } |
||
1424 | |||
1425 | |||
1426 | |||
1427 | |||
1428 | |||
1429 | { |
||
1430 | |||
1431 | switch(sign){ |
||
1432 | |||
1433 | hold=doconstdwordmath(); |
||
1434 | |||
1435 | case 1: |
||
1436 | |||
1437 | break; |
||
1438 | |||
1439 | hold=doconstfloatmath(); |
||
1440 | |||
1441 | case 3: |
||
1442 | |||
1443 | break; |
||
1444 | |||
1445 | hold=doconstqwordmath(); |
||
1446 | |||
1447 | } |
||
1448 | |||
1449 | } |
||
1450 | |||
1451 | int OnlyNumber(int sign) |
||
1452 | |||
1453 | проверить что строка состоит только из цифр. |
||
1454 | |||
1455 | { |
||
1456 | |||
1457 | unsigned char ocha=cha2; |
||
1458 | |||
1459 | unsigned int otok2=tok2; |
||
1460 | |||
1461 | itok.lnumber=CalcNumber(sign); |
||
1462 | |||
1463 | if(itok.type==tp_stopper){ |
||
1464 | |||
1465 | } |
||
1466 | |||
1467 | inptr2=oinptr; |
||
1468 | |||
1469 | tok=tk_number; |
||
1470 | |||
1471 | |||
1472 | |||
1473 | free(bufrm); |
||
1474 | |||
1475 | } |
||
1476 | |||
1477 | free(strinf.bufstr); |
||
1478 | |||
1479 | } |
||
1480 | |||
1481 | } |
||
1482 | |||
1483 | void MultiAssignFloat(int type,int npointr=0) |
||
1484 | |||
1485 | int otok; |
||
1486 | |||
1487 | char *wbuf; |
||
1488 | |||
1489 | char *ofsstr=NULL; |
||
1490 | |||
1491 | wstr=strinf; |
||
1492 | |||
1493 | wtok=itok; |
||
1494 | |||
1495 | bufrm=NULL; |
||
1496 | |||
1497 | nexttok(); |
||
1498 | |||
1499 | int numpointr=0; |
||
1500 | |||
1501 | if(tok==tk_float||tok==tk_double)nexttok(); |
||
1502 | |||
1503 | nexttok(); |
||
1504 | |||
1505 | } |
||
1506 | |||
1507 | if(tok2==tk_assign)MultiAssignFloat(type,numpointr); |
||
1508 | |||
1509 | if(tok==tk_pointer)cpointr(BX,numpointr); |
||
1510 | |||
1511 | tok=tk_dwordvar; |
||
1512 | |||
1513 | } |
||
1514 | |||
1515 | } |
||
1516 | |||
1517 | if(wtok.type==tk_proc){ |
||
1518 | |||
1519 | if(am32)wtok.sib=CODE32; |
||
1520 | |||
1521 | compressoffset(&wtok); |
||
1522 | |||
1523 | else{ |
||
1524 | |||
1525 | if(npointr<=wtok.npointr)getpointeradr(&wtok,wbuf,&wstr,npointr-1,razr,BX); |
||
1526 | |||
1527 | wtok=itok; |
||
1528 | |||
1529 | } |
||
1530 | |||
1531 | op66(r32); |
||
1532 | |||
1533 | op(0xA3); /* MOV [word],AX */ |
||
1534 | |||
1535 | AddUndefOff(2,wtok.name); |
||
1536 | |||
1537 | } |
||
1538 | |||
1539 | else outdword(wtok.number); |
||
1540 | |||
1541 | else{ |
||
1542 | |||
1543 | op66(r32); |
||
1544 | |||
1545 | op(0x89); op(wtok.rm); /* MOV [rmword],reg */ |
||
1546 | |||
1547 | } |
||
1548 | |||
1549 | |||
1550 | |||
1551 | { |
||
1552 | |||
1553 | ITOK wtok; |
||
1554 | |||
1555 | SINFO wstr; |
||
1556 | |||
1557 | int hnumber=0; |
||
1558 | |||
1559 | char *ofsstr=NULL; |
||
1560 | |||
1561 | strinf.bufstr=NULL; |
||
1562 | |||
1563 | wbuf=bufrm; |
||
1564 | |||
1565 | otok=tok; |
||
1566 | |||
1567 | usereg=EAX;//USEONLY_AX; |
||
1568 | |||
1569 | rettype=tk_dword; |
||
1570 | |||
1571 | if(i<9){ |
||
1572 | |||
1573 | rettype=tk_byte; |
||
1574 | |||
1575 | else if(i<17){ |
||
1576 | |||
1577 | nrazr=r16; |
||
1578 | |||
1579 | else if(i>32)nrazr=r64; |
||
1580 | |||
1581 | else{ |
||
1582 | |||
1583 | switch(tok){ |
||
1584 | |||
1585 | ureg=itok.number; |
||
1586 | |||
1587 | if(usereg>ureg)usereg=ureg; |
||
1588 | |||
1589 | case tk_reg: |
||
1590 | |||
1591 | if(usereg>itok.number)usereg=itok.number; |
||
1592 | |||
1593 | } |
||
1594 | |||
1595 | } |
||
1596 | |||
1597 | if(nrazr>razr&&nrazr |
||
1598 | |||
1599 | case r8: |
||
1600 | |||
1601 | break; |
||
1602 | |||
1603 | rettype=tk_word; |
||
1604 | |||
1605 | case r32: |
||
1606 | |||
1607 | break; |
||
1608 | |||
1609 | nexttok(); |
||
1610 | |||
1611 | ofsstr=GetLecsem(tk_assign,tk_semicolon); |
||
1612 | |||
1613 | convert_type(&sign,&rettype,&pointr); |
||
1614 | |||
1615 | nexttok(); |
||
1616 | |||
1617 | } |
||
1618 | |||
1619 | unuseableinput(); |
||
1620 | |||
1621 | ureg=AX; |
||
1622 | |||
1623 | ureg=hnumber=MultiAssign(razr,usereg,numpointr); |
||
1624 | |||
1625 | free(ofsstr); |
||
1626 | |||
1627 | } |
||
1628 | |||
1629 | else{ |
||
1630 | |||
1631 | int reg=idxregs[2]; |
||
1632 | |||
1633 | cpointr(reg,numpointr); |
||
1634 | |||
1635 | if(usereg==USEALLREG){ |
||
1636 | |||
1637 | case tk_reg: |
||
1638 | |||
1639 | usereg=itok.number; |
||
1640 | |||
1641 | case tk_beg: |
||
1642 | |||
1643 | break; |
||
1644 | |||
1645 | usereg=EAX; |
||
1646 | |||
1647 | } |
||
1648 | |||
1649 | switch(rettype){ |
||
1650 | |||
1651 | case tk_byte: |
||
1652 | |||
1653 | ureg=hnumber=usereg; |
||
1654 | |||
1655 | getintoreg(usereg,r16,sign,&ofsstr); |
||
1656 | |||
1657 | /* if(tok2==tk_semicolon&&tok==tk_beg&&usereg<2){ |
||
1658 | |||
1659 | ureg=hnumber=itok.number; |
||
1660 | |||
1661 | break; |
||
1662 | |||
1663 | }*/ |
||
1664 | |||
1665 | if(ofsstr)IDZToReg(ofsstr,usereg,r8); |
||
1666 | |||
1667 | case tk_int: |
||
1668 | |||
1669 | if(tok2==tk_semicolon&&usereg!=0){ |
||
1670 | |||
1671 | // if(tok==tk_reg)ureg=hnumber=itok.number; |
||
1672 | |||
1673 | } |
||
1674 | |||
1675 | if(ofsstr)IDZToReg(ofsstr,usereg,r16); |
||
1676 | |||
1677 | case tk_float: |
||
1678 | |||
1679 | break; |
||
1680 | |||
1681 | if(tok2==tk_semicolon&&usereg!=0&&tok!=tk_floatvar){ |
||
1682 | |||
1683 | // if(tok==tk_reg32)ureg=hnumber=itok.number; |
||
1684 | |||
1685 | } |
||
1686 | |||
1687 | if(tok==tk_floatvar&&tok2==tk_semicolon)tok=tk_dwordvar; |
||
1688 | |||
1689 | } |
||
1690 | |||
1691 | break; |
||
1692 | |||
1693 | } |
||
1694 | |||
1695 | free(ofsstr); |
||
1696 | |||
1697 | } |
||
1698 | |||
1699 | case r8: |
||
1700 | |||
1701 | break; |
||
1702 | |||
1703 | posiblret=tk_word; |
||
1704 | |||
1705 | case r32: |
||
1706 | |||
1707 | break; |
||
1708 | |||
1709 | convert_returnvalue(posiblret,rettype); |
||
1710 | |||
1711 | switch ( otok ) { |
||
1712 | |||
1713 | case tk_wordvar: |
||
1714 | |||
1715 | case tk_dwordvar: |
||
1716 | |||
1717 | #ifdef OPTVARCONST |
||
1718 | |||
1719 | #endif |
||
1720 | |||
1721 | AddRegVar(hnumber,razr,&wtok); |
||
1722 | |||
1723 | op66(nrazr); |
||
1724 | |||
1725 | op(0xA3); /* MOV [word],AX */ |
||
1726 | |||
1727 | AddUndefOff(2,wtok.name); |
||
1728 | |||
1729 | } |
||
1730 | |||
1731 | else outdword(wtok.number); |
||
1732 | |||
1733 | else{ |
||
1734 | |||
1735 | op66(nrazr); |
||
1736 | |||
1737 | op(0x89); op(wtok.rm+hnumber*8); /* MOV [rmword],reg */ |
||
1738 | |||
1739 | } |
||
1740 | |||
1741 | case tk_charvar: |
||
1742 | |||
1743 | #ifdef OPTVARCONST |
||
1744 | |||
1745 | #endif |
||
1746 | |||
1747 | AddRegVar(hnumber,r8,&wtok); |
||
1748 | |||
1749 | outseg(&wtok,1); |
||
1750 | |||
1751 | if(wtok.post==UNDEF_OFSET){ |
||
1752 | |||
1753 | wtok.post=0; |
||
1754 | |||
1755 | if(am32==FALSE)outword(wtok.number); |
||
1756 | |||
1757 | } |
||
1758 | |||
1759 | CheckAllMassiv(wbuf,1,&wstr,&wtok); |
||
1760 | |||
1761 | op(0x88); |
||
1762 | |||
1763 | outaddress(&wtok); |
||
1764 | |||
1765 | break; |
||
1766 | |||
1767 | if(razr!=r64){ |
||
1768 | |||
1769 | op(0x50); //push eax |
||
1770 | |||
1771 | reg2bits(&wtok,razr); |
||
1772 | |||
1773 | op(0x58); //pop eax |
||
1774 | |||
1775 | else{ |
||
1776 | |||
1777 | op(0x50); //push eax |
||
1778 | |||
1779 | op66(r32); |
||
1780 | |||
1781 | |||
1782 | |||
1783 | reg2bits(&wtok,r32); |
||
1784 | |||
1785 | op(0x58); //pop eax |
||
1786 | |||
1787 | outword(0xE8C1); |
||
1788 | |||
1789 | wtok.bit.siz=siz+wtok.bit.ofs-32; |
||
1790 | |||
1791 | wtok.number+=4; |
||
1792 | |||
1793 | op66(r32); |
||
1794 | |||
1795 | } |
||
1796 | |||
1797 | case tk_reg: |
||
1798 | |||
1799 | if(wtok.number!=hnumber){ |
||
1800 | |||
1801 | op66(nrazr); |
||
1802 | |||
1803 | op(0xC0+wtok.number+hnumber*8); //mov reg,AX |
||
1804 | |||
1805 | else waralreadinitreg(regs[nrazr/4][wtok.number],regs[nrazr/4][hnumber]); |
||
1806 | |||
1807 | break; |
||
1808 | |||
1809 | if(razr>r8&&wtok.number>3&&(wtok.number%4)==hnumber)preerror("register AH,BH,CH,DH should be first"); |
||
1810 | |||
1811 | if(RegToReg(hnumber,wtok.number,r8)==NOINREG){ |
||
1812 | |||
1813 | op(0xC0+wtok.number+hnumber*8); //mov beg,AL |
||
1814 | |||
1815 | else waralreadinitreg(begs[wtok.number],begs[hnumber]); |
||
1816 | |||
1817 | break; |
||
1818 | |||
1819 | op(0x8E); /* MOV SEG,AX */ |
||
1820 | |||
1821 | break; |
||
1822 | |||
1823 | thisundefined(wtok.name); |
||
1824 | |||
1825 | return hnumber; |
||
1826 | |||
1827 | |||
1828 | |||
1829 | { |
||
1830 | |||
1831 | unsigned int vop=0,otok,rettype,posiblret; |
||
1832 | |||
1833 | char *wbuf,*rbuf; |
||
1834 | |||
1835 | int retrez=0,pointr=0,hnumber=EAX; |
||
1836 | |||
1837 | char *ofsstr=NULL; |
||
1838 | |||
1839 | #ifdef OPTVARCONST |
||
1840 | |||
1841 | int operand; |
||
1842 | |||
1843 | unsigned int oaddESP=addESP; |
||
1844 | |||
1845 | posiblret=rettype=(sign==0?(razr==r16?tk_word:tk_dword):(razr==r16?tk_int:tk_long)); |
||
1846 | |||
1847 | strinf.bufstr=NULL; |
||
1848 | |||
1849 | wbuf=bufrm; |
||
1850 | |||
1851 | otok=tok; |
||
1852 | |||
1853 | nexttok(); |
||
1854 | |||
1855 | operand=tok; |
||
1856 | |||
1857 | switch(tok){ |
||
1858 | |||
1859 | if(!((tok2==tk_reg||tok2==tk_reg32)&&ScanTok3()==terminater)){ |
||
1860 | |||
1861 | } |
||
1862 | |||
1863 | int retreg; |
||
1864 | |||
1865 | GetEndLex(terminater); |
||
1866 | |||
1867 | if((GetRegVar(&wtok)&(1< |
||
1868 | |||
1869 | if(wbuf)free(wbuf); |
||
1870 | |||
1871 | break; |
||
1872 | |||
1873 | if(razr==r16)tok=tk_reg; |
||
1874 | |||
1875 | itok.number=retreg; |
||
1876 | |||
1877 | reg1=idxregs[1]; reg2=idxregs[2]; |
||
1878 | |||
1879 | if(reg2==itok.number){ |
||
1880 | |||
1881 | } |
||
1882 | |||
1883 | } |
||
1884 | |||
1885 | nexttok(); |
||
1886 | |||
1887 | convert_type(&sign,(int *)&rettype,&pointr); |
||
1888 | |||
1889 | nexttok(); |
||
1890 | |||
1891 | } |
||
1892 | |||
1893 | unuseableinput(); |
||
1894 | |||
1895 | if(tok2==tk_assign){ |
||
1896 | |||
1897 | if(ofsstr){ |
||
1898 | |||
1899 | ofsstr=NULL; |
||
1900 | |||
1901 | next=0; |
||
1902 | |||
1903 | |||
1904 | |||
1905 | CheckMinusNum(); |
||
1906 | |||
1907 | if(itok2.type==tp_opperand){ //сложное выражение |
||
1908 | |||
1909 | if(OnlyNumber(rettype==tk_float?2:sign)){ |
||
1910 | |||
1911 | itok.flag=(unsigned char)postnumflag; |
||
1912 | |||
1913 | goto numbertovar; |
||
1914 | |||
1915 | } |
||
1916 | |||
1917 | } |
||
1918 | |||
1919 | // if(hnumber!=EAX&&(tok==tk_reg||tok==tk_reg32)&&itok.number==EAX)goto labl1; |
||
1920 | |||
1921 | CheckConstVar3(&tok,&itok,razr); |
||
1922 | |||
1923 | switch(tok){ |
||
1924 | |||
1925 | loadconst: |
||
1926 | |||
1927 | #ifdef OPTVARCONST |
||
1928 | |||
1929 | else itok.lnumber&=0xffffffff; |
||
1930 | |||
1931 | waralreadinitvar(wtok.name,itok.number); |
||
1932 | |||
1933 | break; |
||
1934 | |||
1935 | #endif |
||
1936 | |||
1937 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
1938 | |||
1939 | outseg(&wtok,2); |
||
1940 | |||
1941 | op(wtok.rm+0x20); |
||
1942 | |||
1943 | op(0); |
||
1944 | |||
1945 | } |
||
1946 | |||
1947 | |||
1948 | |||
1949 | outseg(&wtok,2); |
||
1950 | |||
1951 | op(wtok.rm+0x8); |
||
1952 | |||
1953 | op(0xFF); |
||
1954 | |||
1955 | } |
||
1956 | |||
1957 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
1958 | |||
1959 | op(0x6A); |
||
1960 | |||
1961 | op66(razr); |
||
1962 | |||
1963 | op(0x8f); |
||
1964 | |||
1965 | outaddress(&wtok); |
||
1966 | |||
1967 | } |
||
1968 | |||
1969 | case tk_postnumber: |
||
1970 | |||
1971 | numbertovar: |
||
1972 | |||
1973 | op66(razr); |
||
1974 | |||
1975 | op(0xC7); //mov word[],number |
||
1976 | |||
1977 | outaddress(&wtok); |
||
1978 | |||
1979 | else if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
1980 | |||
1981 | if(razr==r16){ |
||
1982 | |||
1983 | outword((unsigned int)itok.number); |
||
1984 | |||
1985 | else outdword(itok.number); |
||
1986 | |||
1987 | case tk_apioffset: |
||
1988 | |||
1989 | op66(razr); |
||
1990 | |||
1991 | op(0xC7); //mov word[],number |
||
1992 | |||
1993 | outaddress(&wtok); |
||
1994 | |||
1995 | break; |
||
1996 | |||
1997 | // if(razr==r16)goto labl1; |
||
1998 | |||
1999 | if(razr==r32&&tok==tk_reg)goto labl1; |
||
2000 | |||
2001 | if((unsigned int)itok.number==0){ |
||
2002 | |||
2003 | hnumber=0; |
||
2004 | |||
2005 | else{ |
||
2006 | |||
2007 | KillVar(wtok.name); |
||
2008 | |||
2009 | vop++; |
||
2010 | |||
2011 | CheckAllMassiv(wbuf,razr,&wstr,&wtok,reg1,reg2); |
||
2012 | |||
2013 | outseg(&wtok,2); |
||
2014 | |||
2015 | op((unsigned int)itok.number*8+wtok.rm); |
||
2016 | |||
2017 | } |
||
2018 | |||
2019 | case tk_seg: |
||
2020 | |||
2021 | CheckAllMassiv(wbuf,2,&wstr,&wtok); |
||
2022 | |||
2023 | outseg(&wtok,2); |
||
2024 | |||
2025 | op((unsigned int)itok.number*8+wtok.rm); |
||
2026 | |||
2027 | if((unsigned int)itok.number==FS||(unsigned int)itok.number==GS)if(cpu<3)cpu=3; |
||
2028 | |||
2029 | case tk_string: |
||
2030 | |||
2031 | op66(razr); |
||
2032 | |||
2033 | op(0xC7); |
||
2034 | |||
2035 | outaddress(&wtok); |
||
2036 | |||
2037 | if(am32)dwordvalexpected(); |
||
2038 | |||
2039 | } |
||
2040 | |||
2041 | break; |
||
2042 | |||
2043 | vop=4; |
||
2044 | |||
2045 | intinstack(vop); |
||
2046 | |||
2047 | CheckAllMassiv(wbuf,4,&wstr,&wtok); |
||
2048 | |||
2049 | op(razr==r16?0xDF:0xDB); |
||
2050 | |||
2051 | outaddress(&wtok); |
||
2052 | |||
2053 | fwait3(); |
||
2054 | |||
2055 | break; |
||
2056 | |||
2057 | donew(); |
||
2058 | |||
2059 | clearregstat(); |
||
2060 | |||
2061 | FreeGlobalConst(); |
||
2062 | |||
2063 | if(ofsstr){ |
||
2064 | |||
2065 | ofsstr=NULL; |
||
2066 | |||
2067 | hnumber=0; |
||
2068 | |||
2069 | case tk_delete: |
||
2070 | |||
2071 | terminater=next=0; |
||
2072 | |||
2073 | clearregstat(); |
||
2074 | |||
2075 | FreeGlobalConst(); |
||
2076 | |||
2077 | if(ofsstr)free(ofsstr); |
||
2078 | |||
2079 | break; |
||
2080 | |||
2081 | case tk_dwordvar: |
||
2082 | |||
2083 | goto labl1; |
||
2084 | |||
2085 | case tk_wordvar: |
||
2086 | |||
2087 | pushvar: |
||
2088 | |||
2089 | op66(razr); |
||
2090 | |||
2091 | op(0xFF); // PUSH [dword] |
||
2092 | |||
2093 | outaddress(&itok); |
||
2094 | |||
2095 | op66(razr); |
||
2096 | |||
2097 | op(0x8f); |
||
2098 | |||
2099 | outaddress(&wtok); |
||
2100 | |||
2101 | } |
||
2102 | |||
2103 | default: |
||
2104 | |||
2105 | getfromAX=1; |
||
2106 | |||
2107 | if(hnumber==0)retrez=doalmath(sign,&ofsstr); |
||
2108 | |||
2109 | retrez=getintoreg(hnumber,razr,sign,&ofsstr); |
||
2110 | |||
2111 | } |
||
2112 | |||
2113 | else if(rettype==tk_int||rettype==tk_word){ |
||
2114 | |||
2115 | else retrez=getintoreg(hnumber,r16,sign,&ofsstr); |
||
2116 | |||
2117 | |||
2118 | |||
2119 | getfromAX=0; |
||
2120 | |||
2121 | outseg(&wtok,2); //fistp var |
||
2122 | |||
2123 | op(wtok.rm+0x18); |
||
2124 | |||
2125 | if(sign==0)warningretsign(); |
||
2126 | |||
2127 | hnumber=EAX; |
||
2128 | |||
2129 | else{ |
||
2130 | |||
2131 | else retrez=getintoreg(hnumber,r32,sign,&ofsstr); |
||
2132 | |||
2133 | next=0; |
||
2134 | |||
2135 | } |
||
2136 | |||
2137 | if(getfromAX){ |
||
2138 | |||
2139 | #ifdef OPTVARCONST |
||
2140 | |||
2141 | #endif |
||
2142 | |||
2143 | convert_returnvalue(posiblret,rettype); |
||
2144 | |||
2145 | if(wbuf==NULL&&wstr.bufstr==NULL&&hnumber==0&& |
||
2146 | |||
2147 | (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
2148 | |||
2149 | outseg(&wtok,1); |
||
2150 | |||
2151 | if(wtok.post==UNDEF_OFSET){ |
||
2152 | |||
2153 | wtok.post=0; |
||
2154 | |||
2155 | if(am32==FALSE)outword(wtok.number); //???? |
||
2156 | |||
2157 | } |
||
2158 | |||
2159 | CheckAllMassiv(wbuf,razr,&wstr,&wtok,reg1,reg2); |
||
2160 | |||
2161 | op66(razr); |
||
2162 | |||
2163 | op(0x89); op(wtok.rm+hnumber*8); // MOV [rmword],AX |
||
2164 | |||
2165 | } |
||
2166 | |||
2167 | else ClearReg(hnumber); |
||
2168 | |||
2169 | AddRegVar(hnumber,razr,&wtok); |
||
2170 | |||
2171 | else{ |
||
2172 | |||
2173 | if(vop==0)KillVar(wtok.name); |
||
2174 | |||
2175 | if(ofsstr)free(ofsstr); |
||
2176 | |||
2177 | case tk_minusminus: vop=0x8; |
||
2178 | |||
2179 | #ifdef OPTVARCONST |
||
2180 | |||
2181 | #endif |
||
2182 | |||
2183 | op66(razr); |
||
2184 | |||
2185 | op(0xFF); op(vop+wtok.rm); |
||
2186 | |||
2187 | KillVar(wtok.name); |
||
2188 | |||
2189 | case tk_cdecl: |
||
2190 | |||
2191 | case tk_fastcall: |
||
2192 | |||
2193 | vop=tok; |
||
2194 | |||
2195 | if(tok!=tk_openbracket){ |
||
2196 | |||
2197 | FindStopTok(); |
||
2198 | |||
2199 | case tk_openbracket: //вызов процедуры по адресу в регистре |
||
2200 | |||
2201 | int i; |
||
2202 | |||
2203 | switch ( vop ) { |
||
2204 | |||
2205 | case tk_stdcall: |
||
2206 | |||
2207 | break; |
||
2208 | |||
2209 | doparams(); |
||
2210 | |||
2211 | case tk_fastcall: |
||
2212 | |||
2213 | break; |
||
2214 | |||
2215 | if(comfile==file_w32)swapparam(); |
||
2216 | |||
2217 | } |
||
2218 | |||
2219 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2220 | |||
2221 | op(0xFF); op(0x10+wtok.rm); |
||
2222 | |||
2223 | clearregstat(); |
||
2224 | |||
2225 | FreeGlobalConst(); |
||
2226 | |||
2227 | if(i)CorrectStack(i); |
||
2228 | |||
2229 | case tk_xorequals: vop+=0x08; |
||
2230 | |||
2231 | case tk_andequals: vop+=0x18; |
||
2232 | |||
2233 | case tk_plusequals: |
||
2234 | |||
2235 | if(tok==tk_float){ |
||
2236 | |||
2237 | doeaxfloatmath(tk_reg32,AX); |
||
2238 | |||
2239 | } |
||
2240 | |||
2241 | if(tok==tk_number){ |
||
2242 | |||
2243 | next=0; |
||
2244 | |||
2245 | tok=tk_number; |
||
2246 | |||
2247 | } |
||
2248 | |||
2249 | retrez=razr==r16?tk_reg:tk_reg32; |
||
2250 | |||
2251 | |||
2252 | |||
2253 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2254 | |||
2255 | outseg(&wtok,2); |
||
2256 | |||
2257 | outaddress(&wtok); |
||
2258 | |||
2259 | } |
||
2260 | |||
2261 | switch(tok){ |
||
2262 | |||
2263 | case tk_postnumber: |
||
2264 | |||
2265 | num: |
||
2266 | |||
2267 | if(tok==tk_number&&(itok.flag&f_reloc)==0){ |
||
2268 | |||
2269 | } |
||
2270 | |||
2271 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2272 | |||
2273 | outseg(&wtok,2); |
||
2274 | |||
2275 | if(vop)vop=8; |
||
2276 | |||
2277 | outaddress(&wtok); |
||
2278 | |||
2279 | else if(tok!=tk_undefofs&&tok!=tk_postnumber&&(itok.flag&f_reloc)==0&& |
||
2280 | |||
2281 | op(0x83); |
||
2282 | |||
2283 | outaddress(&wtok); |
||
2284 | |||
2285 | } |
||
2286 | |||
2287 | op(0x81); |
||
2288 | |||
2289 | outaddress(&wtok); |
||
2290 | |||
2291 | else if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
2292 | |||
2293 | razr==r16?outword(itok.number):outdword(itok.number); |
||
2294 | |||
2295 | if(next==0)tok=otok; |
||
2296 | |||
2297 | case tk_apioffset: |
||
2298 | |||
2299 | op66(razr); |
||
2300 | |||
2301 | op(0x81); |
||
2302 | |||
2303 | outaddress(&wtok); |
||
2304 | |||
2305 | break; |
||
2306 | |||
2307 | if(razr==r16)goto defxor; |
||
2308 | |||
2309 | if(tok==tk_reg&&razr==r32)goto defxor; |
||
2310 | |||
2311 | initconst=CheckUpdRegToConst(itok.number,&wtok,operand,razr); |
||
2312 | |||
2313 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2314 | |||
2315 | outseg(&wtok,2); |
||
2316 | |||
2317 | outaddress(&wtok); |
||
2318 | |||
2319 | default: |
||
2320 | |||
2321 | retrez=razr==r16?tk_reg:tk_reg32; |
||
2322 | |||
2323 | if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP; |
||
2324 | |||
2325 | op66(razr); |
||
2326 | |||
2327 | op(0x01+vop); op(wtok.rm); /* ADD [anyword],AX */ |
||
2328 | |||
2329 | next=0; |
||
2330 | |||
2331 | } |
||
2332 | |||
2333 | // puts(wtok.name); |
||
2334 | |||
2335 | break; |
||
2336 | |||
2337 | getoperand(am32==TRUE?EAX:BX); |
||
2338 | |||
2339 | if(tok==tk_number){ |
||
2340 | |||
2341 | if(itok.number==0){ |
||
2342 | |||
2343 | goto getfromax; |
||
2344 | |||
2345 | #ifdef OPTVARCONST |
||
2346 | |||
2347 | initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand); |
||
2348 | |||
2349 | #endif |
||
2350 | |||
2351 | else getinto_reg(otok,&wtok,wbuf,&wstr,razr,hnumber); |
||
2352 | |||
2353 | RegMulNum(hnumber,itok.number,razr,sign,(int *)&vop,itok.flag); |
||
2354 | |||
2355 | } |
||
2356 | |||
2357 | if(hnumber==0)do_e_axmath(sign,razr,&ofsstr); |
||
2358 | |||
2359 | if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar)){ |
||
2360 | |||
2361 | oaddESP=addESP; |
||
2362 | |||
2363 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2364 | |||
2365 | if(hnumber==0){ |
||
2366 | |||
2367 | op(0xF7); // imul/mul var |
||
2368 | |||
2369 | else op(0x20+wtok.rm); |
||
2370 | |||
2371 | else{ |
||
2372 | |||
2373 | outword(0xaf0f); |
||
2374 | |||
2375 | } |
||
2376 | |||
2377 | next=0; |
||
2378 | |||
2379 | goto getfromax; |
||
2380 | |||
2381 | getoperand(am32==TRUE?EAX:BX); |
||
2382 | |||
2383 | if(itok2.type==tp_stopper){ |
||
2384 | |||
2385 | if(itok.number==1)break; |
||
2386 | |||
2387 | if((itok.flag&f_reloc)==0){ |
||
2388 | |||
2389 | } |
||
2390 | |||
2391 | getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE); |
||
2392 | |||
2393 | next=0; |
||
2394 | |||
2395 | } |
||
2396 | |||
2397 | } |
||
2398 | |||
2399 | do_e_axmath(sign,razr,&ofsstr); |
||
2400 | |||
2401 | else op(0x90+ECX); //xchg ax,Cx |
||
2402 | |||
2403 | wtok.number+=addESP-oaddESP; |
||
2404 | |||
2405 | } |
||
2406 | |||
2407 | getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE); |
||
2408 | |||
2409 | op66(razr); |
||
2410 | |||
2411 | if(sign)op(0xF8+ECX); // IDIV CX |
||
2412 | |||
2413 | next=0; |
||
2414 | |||
2415 | KillVar(wtok.name); |
||
2416 | |||
2417 | case tk_swap: |
||
2418 | |||
2419 | int regdi; |
||
2420 | |||
2421 | getoperand(); |
||
2422 | |||
2423 | bufrm=NULL; |
||
2424 | |||
2425 | switch(tok){ |
||
2426 | |||
2427 | if(razr==r16)swaperror(); |
||
2428 | |||
2429 | if(tok==tk_reg&&razr==r32)swaperror(); |
||
2430 | |||
2431 | initconst=SwapVarRegConst(itok.number,&wtok,razr); |
||
2432 | |||
2433 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2434 | |||
2435 | outseg(&wtok,2); |
||
2436 | |||
2437 | op((unsigned int)itok.number*8+wtok.rm); |
||
2438 | |||
2439 | ClearReg(itok.number); |
||
2440 | |||
2441 | case tk_qwordvar: |
||
2442 | |||
2443 | case tk_dwordvar: |
||
2444 | |||
2445 | case tk_intvar: |
||
2446 | |||
2447 | if((tok==tk_intvar||tok==tk_wordvar)&&razr==r32)swaperror(); |
||
2448 | |||
2449 | ClearVarByNum(&itok); |
||
2450 | |||
2451 | if(hnumber==0)getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE); |
||
2452 | |||
2453 | if(regoverstack&&(!((bufrm||strinf.bufstr)&&(wbuf||wstr.bufstr)))){ |
||
2454 | |||
2455 | op66(razr); |
||
2456 | |||
2457 | op(0xFF); // PUSH [dword] |
||
2458 | |||
2459 | outaddress(&itok); |
||
2460 | |||
2461 | op66(razr); |
||
2462 | |||
2463 | op(0xFF); // PUSH [dword] |
||
2464 | |||
2465 | outaddress(&wtok); |
||
2466 | |||
2467 | CheckAllMassiv(bufrm,razr,&strinf); |
||
2468 | |||
2469 | outseg(&itok,2); |
||
2470 | |||
2471 | op(itok.rm); |
||
2472 | |||
2473 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2474 | |||
2475 | outseg(&wtok,2); |
||
2476 | |||
2477 | op(wtok.rm); |
||
2478 | |||
2479 | |||
2480 | |||
2481 | } |
||
2482 | |||
2483 | } |
||
2484 | |||
2485 | op66(razr); |
||
2486 | |||
2487 | op(0x87); /* XCHG AX,[wloc] */ |
||
2488 | |||
2489 | outaddress(&itok); |
||
2490 | |||
2491 | case tk_seg: |
||
2492 | |||
2493 | op66(r16); |
||
2494 | |||
2495 | op(0xC0+(unsigned int)itok.number*8); |
||
2496 | |||
2497 | op66(r16); |
||
2498 | |||
2499 | |||
2500 | |||
2501 | outaddress(&wtok); |
||
2502 | |||
2503 | op(0x8E); /* MOV seg,AX */ |
||
2504 | |||
2505 | break; |
||
2506 | |||
2507 | if(razr==r16)swaperror(); |
||
2508 | |||
2509 | CheckAllMassiv(wbuf,4,&wstr,&wtok); |
||
2510 | |||
2511 | op(0xDB); |
||
2512 | |||
2513 | outaddress(&wtok); |
||
2514 | |||
2515 | outseg(&itok,2); //fld val |
||
2516 | |||
2517 | op(itok.rm); |
||
2518 | |||
2519 | } |
||
2520 | |||
2521 | CheckInitBP(); |
||
2522 | |||
2523 | outword(0x6a); |
||
2524 | |||
2525 | op66(r32); //push var |
||
2526 | |||
2527 | addESP+=8; |
||
2528 | |||
2529 | op(0xFF); |
||
2530 | |||
2531 | outaddress(&wtok); |
||
2532 | |||
2533 | CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
2534 | |||
2535 | op(0xd9); |
||
2536 | |||
2537 | outaddress(&itok); |
||
2538 | |||
2539 | if(optimizespeed||am32==0){ |
||
2540 | |||
2541 | op(8); |
||
2542 | |||
2543 | else{ |
||
2544 | |||
2545 | op(0x58); // pop EAX |
||
2546 | |||
2547 | |||
2548 | |||
2549 | outseg(&wtok,2);//fistp var |
||
2550 | |||
2551 | op(wtok.rm+0x18); |
||
2552 | |||
2553 | outseg(&itok,2); //fstp val |
||
2554 | |||
2555 | op(itok.rm+0x18); |
||
2556 | |||
2557 | fwait3(); |
||
2558 | |||
2559 | default: swaperror(); break; |
||
2560 | |||
2561 | break; |
||
2562 | |||
2563 | vop=8; |
||
2564 | |||
2565 | case tk_llequals: |
||
2566 | |||
2567 | getoperand(am32==TRUE?ECX:BX); |
||
2568 | |||
2569 | doalmath(0,&ofsstr); // all shifts unsigned byte |
||
2570 | |||
2571 | ClearReg(CX); |
||
2572 | |||
2573 | if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP; |
||
2574 | |||
2575 | op66(razr); |
||
2576 | |||
2577 | op(0xD3); op(0x20+vop+wtok.rm); // SHL [rmword],CL |
||
2578 | |||
2579 | warningreg(begs[1]); |
||
2580 | |||
2581 | } |
||
2582 | |||
2583 | #ifdef OPTVARCONST |
||
2584 | |||
2585 | initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand); |
||
2586 | |||
2587 | #endif |
||
2588 | |||
2589 | if((unsigned int)itok.number==1){ |
||
2590 | |||
2591 | outseg(&wtok,2); |
||
2592 | |||
2593 | outaddress(&wtok); |
||
2594 | |||
2595 | else if((unsigned int)itok.number!=0){ |
||
2596 | |||
2597 | getintobeg(CL,&ofsstr); |
||
2598 | |||
2599 | outseg(&wtok,2); |
||
2600 | |||
2601 | outaddress(&wtok); |
||
2602 | |||
2603 | ClearReg(CX); |
||
2604 | |||
2605 | } |
||
2606 | |||
2607 | op66(razr); |
||
2608 | |||
2609 | op(0xC1); op(0x20+vop+wtok.rm); /* SHL [rmword],imm8 */ |
||
2610 | |||
2611 | if(cpu<2)cpu=2; |
||
2612 | |||
2613 | op((unsigned int)itok.number); |
||
2614 | |||
2615 | } |
||
2616 | |||
2617 | if(tok!=tk_beg||(unsigned int)itok.number!=CL){ |
||
2618 | |||
2619 | warningreg(begs[1]); |
||
2620 | |||
2621 | next=0; |
||
2622 | |||
2623 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2624 | |||
2625 | outseg(&wtok,2); |
||
2626 | |||
2627 | outaddress(&wtok); |
||
2628 | |||
2629 | break; |
||
2630 | |||
2631 | } |
||
2632 | |||
2633 | if(initconst==FALSE)ClearVarByNum(&wtok); |
||
2634 | |||
2635 | if(next)nexttok(); |
||
2636 | |||
2637 | if(razr==r32&&cpu<3)cpu=3; |
||
2638 | |||
2639 | } |
||
2640 | |||
2641 | int dobytevar(int sign,int terminater) // byte, char |
||
2642 | |||
2643 | unsigned char next=1,getfromAX=0; |
||
2644 | |||
2645 | ITOK btok; |
||
2646 | |||
2647 | int retrez=0,pointr=0,hnumber=AL; |
||
2648 | |||
2649 | int numpointr=0; |
||
2650 | |||
2651 | #ifdef OPTVARCONST |
||
2652 | |||
2653 | int operand; |
||
2654 | |||
2655 | unsigned int oaddESP=addESP; |
||
2656 | |||
2657 | bstr=strinf; |
||
2658 | |||
2659 | btok=itok; |
||
2660 | |||
2661 | bufrm=NULL; |
||
2662 | |||
2663 | while(RmEqualReg(hnumber,itok.rm,itok.sib))hnumber++; |
||
2664 | |||
2665 | #ifdef OPTVARCONST |
||
2666 | |||
2667 | #endif |
||
2668 | |||
2669 | case tk_assign: |
||
2670 | |||
2671 | ofsstr=GetLecsem(terminater); |
||
2672 | |||
2673 | if(ofsstr){ |
||
2674 | |||
2675 | if((retreg=CheckIDZReg(ofsstr,AX,r8))!=NOINREG){ |
||
2676 | |||
2677 | tok=tk_beg; |
||
2678 | |||
2679 | goto regtovar; |
||
2680 | |||
2681 | } |
||
2682 | |||
2683 | convert_type(&sign,(int *)&rettype,&pointr); |
||
2684 | |||
2685 | nexttok(); |
||
2686 | |||
2687 | } |
||
2688 | |||
2689 | if(tok2==tk_assign){ |
||
2690 | |||
2691 | if(ofsstr){ |
||
2692 | |||
2693 | ofsstr=NULL; |
||
2694 | |||
2695 | next=0; |
||
2696 | |||
2697 | } |
||
2698 | |||
2699 | CheckMinusNum(); |
||
2700 | |||
2701 | if(rettype!=tk_float&&tok==tk_number){ //проверка и суммирование чисел |
||
2702 | |||
2703 | next=0; |
||
2704 | |||
2705 | } |
||
2706 | |||
2707 | goto labl1; |
||
2708 | |||
2709 | else{ |
||
2710 | |||
2711 | if(tok>=tk_charvar&&tok<=tk_doublevar&&itok.npointr==0){ |
||
2712 | |||
2713 | } |
||
2714 | |||
2715 | switch(tok){ |
||
2716 | |||
2717 | numbertovar: |
||
2718 | |||
2719 | if((initconst=Const2Var(&btok,itok.lnumber&0Xff,itok.rm))==FALSE){ |
||
2720 | |||
2721 | initconst=TRUE; |
||
2722 | |||
2723 | } |
||
2724 | |||
2725 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2726 | |||
2727 | op(0xC6); |
||
2728 | |||
2729 | outaddress(&btok); |
||
2730 | |||
2731 | break; |
||
2732 | |||
2733 | case tk_reg: |
||
2734 | |||
2735 | case tk_beg: |
||
2736 | |||
2737 | if((unsigned int)itok.number==0){ |
||
2738 | |||
2739 | hnumber=0; |
||
2740 | |||
2741 | else{ |
||
2742 | |||
2743 | AddRegVar(itok.number,r8,&btok); |
||
2744 | |||
2745 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2746 | |||
2747 | op(0x88); |
||
2748 | |||
2749 | outaddress(&btok); |
||
2750 | |||
2751 | break; |
||
2752 | |||
2753 | default: |
||
2754 | |||
2755 | if(rettype==tk_char||rettype==tk_byte){ |
||
2756 | |||
2757 | else retrez=getintobeg(hnumber,&ofsstr); |
||
2758 | |||
2759 | else if(rettype==tk_int||rettype==tk_word){ |
||
2760 | |||
2761 | else retrez=getintoreg(hnumber,r16,sign,&ofsstr); |
||
2762 | |||
2763 | else if(rettype==tk_float){ |
||
2764 | |||
2765 | rettype=tk_long; |
||
2766 | |||
2767 | } |
||
2768 | |||
2769 | if(hnumber==0)retrez=do_e_axmath(sign,r32,&ofsstr); |
||
2770 | |||
2771 | } |
||
2772 | |||
2773 | next=0; |
||
2774 | |||
2775 | } |
||
2776 | |||
2777 | if(getfromAX){ |
||
2778 | |||
2779 | #ifdef OPTVARCONST |
||
2780 | |||
2781 | #endif |
||
2782 | |||
2783 | convert_returnvalue(posiblret,rettype); |
||
2784 | |||
2785 | if(bbuf==NULL&&bstr.bufstr==NULL&&hnumber==0&&((btok.rm==rm_d16&&btok.sib==CODE16)||(btok.rm==rm_d32&&(btok.sib==CODE32||btok.sib==0)))){ |
||
2786 | |||
2787 | op(0xA2); // MOV [byte],AL |
||
2788 | |||
2789 | AddUndefOff(2,btok.name); |
||
2790 | |||
2791 | } |
||
2792 | |||
2793 | else outdword(btok.number); |
||
2794 | |||
2795 | else{ |
||
2796 | |||
2797 | outseg(&btok,2); // MOV [rmbyte],AL |
||
2798 | |||
2799 | op(btok.rm+hnumber*8); |
||
2800 | |||
2801 | } |
||
2802 | |||
2803 | else ClearReg(hnumber); |
||
2804 | |||
2805 | AddRegVar(hnumber,r8,&btok); |
||
2806 | |||
2807 | else if(vop)KillVar(btok.name); |
||
2808 | |||
2809 | break; |
||
2810 | |||
2811 | getoperand(am32==TRUE?EAX:BX); |
||
2812 | |||
2813 | if(itok.number==1)break; |
||
2814 | |||
2815 | outword(0xB0+hnumber); |
||
2816 | |||
2817 | } |
||
2818 | |||
2819 | if((itok.flag&f_reloc)==0){ |
||
2820 | |||
2821 | } |
||
2822 | |||
2823 | } |
||
2824 | |||
2825 | hnumber=0; |
||
2826 | |||
2827 | btok.number+=addESP-oaddESP; |
||
2828 | |||
2829 | } |
||
2830 | |||
2831 | outseg(&btok,2); |
||
2832 | |||
2833 | if(sign)op(0x28+btok.rm); |
||
2834 | |||
2835 | outaddress(&btok); |
||
2836 | |||
2837 | KillVar(btok.name); |
||
2838 | |||
2839 | case tk_divequals: |
||
2840 | |||
2841 | getoperand(am32==TRUE?EAX:BX); |
||
2842 | |||
2843 | if(tok==tk_number){ |
||
2844 | |||
2845 | #ifdef OPTVARCONST |
||
2846 | |||
2847 | initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,tk_div); |
||
2848 | |||
2849 | |||
2850 | |||
2851 | getintobeg(CL,&ofsstr); |
||
2852 | |||
2853 | |||
2854 | |||
2855 | doalmath(sign,&ofsstr); |
||
2856 | |||
2857 | if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar)){ |
||
2858 | |||
2859 | oaddESP=addESP; |
||
2860 | |||
2861 | } |
||
2862 | |||
2863 | else xorAHAH(); |
||
2864 | |||
2865 | warningreg(begs[3]); |
||
2866 | |||
2867 | if(sign)op(0xF8+CL); // IDIV CL |
||
2868 | |||
2869 | next=0; |
||
2870 | |||
2871 | KillVar(btok.name); |
||
2872 | |||
2873 | case tk_minusminus: vop=0x8; |
||
2874 | |||
2875 | #ifdef OPTVARCONST |
||
2876 | |||
2877 | #endif |
||
2878 | |||
2879 | outseg(&btok,2); |
||
2880 | |||
2881 | op(vop+btok.rm); |
||
2882 | |||
2883 | KillVar(btok.name); |
||
2884 | |||
2885 | case tk_xorequals: vop+=0x08; |
||
2886 | |||
2887 | case tk_andequals: vop+=0x18; |
||
2888 | |||
2889 | case tk_plusequals: |
||
2890 | |||
2891 | getoperand(am32==TRUE?EAX:BX); |
||
2892 | |||
2893 | if(tok==tk_number){ |
||
2894 | |||
2895 | next=0; |
||
2896 | |||
2897 | tok=tk_number; |
||
2898 | |||
2899 | |||
2900 | |||
2901 | doalmath(sign,&ofsstr); |
||
2902 | |||
2903 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2904 | |||
2905 | op(vop); op(btok.rm); // ADD [anybyte],AL |
||
2906 | |||
2907 | next=0; |
||
2908 | |||
2909 | } |
||
2910 | |||
2911 | switch(tok){ |
||
2912 | |||
2913 | num: |
||
2914 | |||
2915 | if((itok.flag&f_reloc)==0){ |
||
2916 | |||
2917 | } |
||
2918 | |||
2919 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2920 | |||
2921 | if(itok.number==1&&(vop==0||vop==0x28)){ |
||
2922 | |||
2923 | op(0xFE); |
||
2924 | |||
2925 | outaddress(&btok); |
||
2926 | |||
2927 | else{ |
||
2928 | |||
2929 | op(vop+btok.rm); |
||
2930 | |||
2931 | op((unsigned int)itok.number); |
||
2932 | |||
2933 | if(next==0)tok=otok; |
||
2934 | |||
2935 | case tk_beg: |
||
2936 | |||
2937 | initconst=CheckUpdRegToConst(itok.number,&btok,operand,r8); |
||
2938 | |||
2939 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2940 | |||
2941 | op(vop); |
||
2942 | |||
2943 | outaddress(&btok); |
||
2944 | |||
2945 | case tk_seg: segbyteerror(); break; |
||
2946 | |||
2947 | retrez=tk_reg; |
||
2948 | |||
2949 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2950 | |||
2951 | op(vop); op(btok.rm); /* ADD [anybyte],AL */ |
||
2952 | |||
2953 | next=0; |
||
2954 | |||
2955 | } |
||
2956 | |||
2957 | break; |
||
2958 | |||
2959 | KillVar(btok.name); |
||
2960 | |||
2961 | rbuf=bufrm; |
||
2962 | |||
2963 | |||
2964 | |||
2965 | #ifdef OPTVARCONST |
||
2966 | |||
2967 | #endif |
||
2968 | |||
2969 | outseg(&btok,2); |
||
2970 | |||
2971 | op((unsigned int)itok.number*8+btok.rm); |
||
2972 | |||
2973 | ClearReg(itok.number>3?itok.number-4:itok.number); |
||
2974 | |||
2975 | case tk_bytevar: |
||
2976 | |||
2977 | #ifdef OPTVARCONST |
||
2978 | |||
2979 | #endif |
||
2980 | |||
2981 | else getinto_reg(otok,&btok,bbuf,&bstr,r8,hnumber); |
||
2982 | |||
2983 | outseg(&itok,2); |
||
2984 | |||
2985 | op(itok.rm+hnumber*8); |
||
2986 | |||
2987 | KillVar(itok.name); |
||
2988 | |||
2989 | default: swaperror(); break; |
||
2990 | |||
2991 | break; |
||
2992 | |||
2993 | vop=8; |
||
2994 | |||
2995 | case tk_llequals: |
||
2996 | |||
2997 | getoperand(am32==TRUE?ECX:BX); |
||
2998 | |||
2999 | doalmath(0,&ofsstr); // all shifts unsigned byte |
||
3000 | |||
3001 | if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar))btok.number+=addESP-oaddESP; |
||
3002 | |||
3003 | outseg(&btok,2); |
||
3004 | |||
3005 | outaddress(&btok); |
||
3006 | |||
3007 | ClearReg(CX); |
||
3008 | |||
3009 | next=0; |
||
3010 | |||
3011 | else if(tok==tk_number){ |
||
3012 | |||
3013 | if((itok.flag&f_reloc)==0){ |
||
3014 | |||
3015 | } |
||
3016 | |||
3017 | if((unsigned int)itok.number==1){ |
||
3018 | |||
3019 | outseg(&btok,2); |
||
3020 | |||
3021 | outaddress(&btok); |
||
3022 | |||
3023 | else if((unsigned int)itok.number!=0){ |
||
3024 | |||
3025 | if(chip<2){ |
||
3026 | |||
3027 | outseg(&btok,2); |
||
3028 | |||
3029 | outaddress(&btok); |
||
3030 | |||
3031 | ClearReg(CX); |
||
3032 | |||
3033 | } |
||
3034 | |||
3035 | outseg(&btok,2); |
||
3036 | |||
3037 | outaddress(&btok); |
||
3038 | |||
3039 | } |
||
3040 | |||
3041 | } |
||
3042 | |||
3043 | else{ |
||
3044 | |||
3045 | getintobeg(CL,&ofsstr); |
||
3046 | |||
3047 | ClearReg(CX); |
||
3048 | |||
3049 | } |
||
3050 | |||
3051 | outseg(&btok,2); |
||
3052 | |||
3053 | outaddress(&btok); |
||
3054 | |||
3055 | break; |
||
3056 | |||
3057 | } |
||
3058 | |||
3059 | if(initconst==FALSE)ClearVarByNum(&btok); |
||
3060 | |||
3061 | if(next)nexttok(); |
||
3062 | |||
3063 | return retrez; |
||
3064 | |||
3065 | |||
3066 | |||
3067 | { |
||
3068 | |||
3069 | int vop=0; |
||
3070 | |||
3071 | switch(gtok){ |
||
3072 | |||
3073 | case tk_longvar: |
||
3074 | |||
3075 | longvar: |
||
3076 | |||
3077 | op66(razr); |
||
3078 | |||
3079 | op(0x8B); |
||
3080 | |||
3081 | outaddress(gstok); |
||
3082 | |||
3083 | break; |
||
3084 | |||
3085 | vop=8; |
||
3086 | |||
3087 | i=2; |
||
3088 | |||
3089 | case tk_bytevar: |
||
3090 | |||
3091 | CheckAllMassiv(gbuf,i,gstr,gstok,reg1,reg2); |
||
3092 | |||
3093 | op(0x8A); |
||
3094 | |||
3095 | outaddress(gstok); |
||
3096 | |||
3097 | |||
3098 | |||
3099 | } |
||
3100 | |||
3101 | void getinto_e_ax(int sign,int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr,int razr,int useAX) |
||
3102 | |||
3103 | unsigned int i=0; |
||
3104 | |||
3105 | int reg1=idxregs[0],reg2=idxregs[1]; |
||
3106 | |||
3107 | reg1=useAX==FALSE?EAX:idxregs[0]; |
||
3108 | |||
3109 | } |
||
3110 | |||
3111 | switch(gtok){ |
||
3112 | |||
3113 | vop=gstok->bit.siz+gstok->bit.ofs; |
||
3114 | |||
3115 | if(vop<=32)i=r32; |
||
3116 | |||
3117 | bits2reg(AX,((unsigned int)razr>i?razr:i)); |
||
3118 | |||
3119 | case tk_postnumber: |
||
3120 | |||
3121 | op(0xB8); /* MOV EAX,# */ |
||
3122 | |||
3123 | razr==r16?outword(gstok->number):outdword(gstok->number); |
||
3124 | |||
3125 | break; |
||
3126 | |||
3127 | CheckAllMassiv(gbuf,gstok->size,gstr,gstok,reg1,reg2); |
||
3128 | |||
3129 | op66(razr); |
||
3130 | |||
3131 | if(gstok->post==0)outseg(gstok,2); |
||
3132 | |||
3133 | if(gstok->post!=0&&gstok->post!=UNDEF_OFSET){ |
||
3134 | |||
3135 | i=outptr; |
||
3136 | |||
3137 | setwordpost(gstok); |
||
3138 | |||
3139 | } |
||
3140 | |||
3141 | } |
||
3142 | |||
3143 | ClearReg(AX); |
||
3144 | |||
3145 | else nexttok(); |
||
3146 | |||
3147 | case tk_doublevar: |
||
3148 | |||
3149 | case tk_floatvar: |
||
3150 | |||
3151 | if(cpu<3)cpu=3; |
||
3152 | |||
3153 | op(0x50); //push EAX |
||
3154 | |||
3155 | addESP+=4; |
||
3156 | |||
3157 | outseg(gstok,2); //fld floatvar |
||
3158 | |||
3159 | op(gstok->rm); |
||
3160 | |||
3161 | fistp_stack(); |
||
3162 | |||
3163 | op(0x58); //pop EAX |
||
3164 | |||
3165 | RestoreBP(); |
||
3166 | |||
3167 | break; |
||
3168 | |||
3169 | i=4; |
||
3170 | |||
3171 | case tk_longvar: |
||
3172 | |||
3173 | longvar: |
||
3174 | |||
3175 | op66(razr); |
||
3176 | |||
3177 | op(0xA1); |
||
3178 | |||
3179 | if(am32==FALSE)outword((unsigned int)gstok->number); |
||
3180 | |||
3181 | } |
||
3182 | |||
3183 | CheckAllMassiv(gbuf,i,gstr,gstok,reg1,reg2); |
||
3184 | |||
3185 | outseg(gstok,2); |
||
3186 | |||
3187 | op(gstok->rm); |
||
3188 | |||
3189 | } |
||
3190 | |||
3191 | break; |
||
3192 | |||
3193 | vop=8; |
||
3194 | |||
3195 | i=2; |
||
3196 | |||
3197 | i=1; |
||
3198 | |||
3199 | movxx: |
||
3200 | |||
3201 | op66(razr); |
||
3202 | |||
3203 | op(0x0F); op(0xB6+vop+i); op(gstok->rm); |
||
3204 | |||
3205 | ClearReg(AX); |
||
3206 | |||
3207 | case tk_charvar: |
||
3208 | |||
3209 | if(razr==r16){ |
||
3210 | |||
3211 | outseg(gstok,1); |
||
3212 | |||
3213 | if(am32==FALSE)outword(gstok->number); |
||
3214 | |||
3215 | } |
||
3216 | |||
3217 | CheckAllMassiv(gbuf,1,gstr,gstok,reg1,reg2); |
||
3218 | |||
3219 | op(0x8A); op(gstok->rm); |
||
3220 | |||
3221 | } |
||
3222 | |||
3223 | ClearReg(AX); |
||
3224 | |||
3225 | } |
||
3226 | |||
3227 | case tk_bytevar: |
||
3228 | |||
3229 | if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){ |
||
3230 | |||
3231 | if(i)op66(r16); |
||
3232 | |||
3233 | op(0xA0+i); |
||
3234 | |||
3235 | else outdword(gstok->number); |
||
3236 | |||
3237 | break; |
||
3238 | |||
3239 | if((chip>=3&&(!optimizespeed))||RmEqualReg(AX,gstok->rm,gstok->sib))goto movxx; |
||
3240 | |||
3241 | CheckAllMassiv(gbuf,1+i,gstr,gstok,SI,reg2); |
||
3242 | |||
3243 | outseg(gstok,2); |
||
3244 | |||
3245 | outaddress(gstok); |
||
3246 | |||
3247 | case tk_beg: |
||
3248 | |||
3249 | xorAHAH(); |
||
3250 | |||
3251 | break; |
||
3252 | |||
3253 | if(optimizespeed&&chip>3&&chip<7){ |
||
3254 | |||
3255 | if(razr==r32)goto movxxr; |
||
3256 | |||
3257 | op(0x88); |
||
3258 | |||
3259 | } |
||
3260 | |||
3261 | outword(0xFCC0); //sar ah,7 |
||
3262 | |||
3263 | } |
||
3264 | |||
3265 | if(razr==r32&&(gstok->number==AL||gstok->number==AH)){ |
||
3266 | |||
3267 | /* op(0x88); |
||
3268 | |||
3269 | xorEAXEAX(); |
||
3270 | |||
3271 | warningreg(begs[1]); |
||
3272 | |||
3273 | } |
||
3274 | |||
3275 | else{ |
||
3276 | |||
3277 | op(0x88); |
||
3278 | |||
3279 | } |
||
3280 | |||
3281 | ClearReg(AX); |
||
3282 | |||
3283 | } |
||
3284 | |||
3285 | if(chip>2||razr==r32){ |
||
3286 | |||
3287 | if(sign)outword(0xBE0F); |
||
3288 | |||
3289 | op(0xC0+(unsigned int)gstok->number); // MOVxX AX,beg |
||
3290 | |||
3291 | else{ |
||
3292 | |||
3293 | op(0xC0+gstok->number*8); |
||
3294 | |||
3295 | else xorAHAH(); |
||
3296 | |||
3297 | ClearReg(AX); |
||
3298 | |||
3299 | case tk_reg: |
||
3300 | |||
3301 | if(tok2==tk_openbracket){ //вызов процедуры по адресу в регистре |
||
3302 | |||
3303 | nexttok(); |
||
3304 | |||
3305 | if(comfile==file_w32)swapparam(); |
||
3306 | |||
3307 | op66(r16); |
||
3308 | |||
3309 | op(0xD0+reg1); /* CALL reg with stack params */ |
||
3310 | |||
3311 | FreeGlobalConst(); |
||
3312 | |||
3313 | clearregstat(); |
||
3314 | |||
3315 | } |
||
3316 | |||
3317 | if(gstok->number==AX){ |
||
3318 | |||
3319 | /* op66(r16); |
||
3320 | |||
3321 | xorEAXEAX(); |
||
3322 | |||
3323 | outword(0xC889); //mov aX,cX |
||
3324 | |||
3325 | } |
||
3326 | |||
3327 | xorEAXEAX(); |
||
3328 | |||
3329 | op(0x89); |
||
3330 | |||
3331 | } |
||
3332 | |||
3333 | else{ |
||
3334 | |||
3335 | op66(r32); |
||
3336 | |||
3337 | if(sign)op(0xBF); |
||
3338 | |||
3339 | op(0xC0+gstok->number); |
||
3340 | |||
3341 | RegToReg(AX,gstok->number,razr); |
||
3342 | |||
3343 | } |
||
3344 | |||
3345 | if(tok2==tk_openbracket){ //вызов процедуры по адресу в регистре |
||
3346 | |||
3347 | nexttok(); |
||
3348 | |||
3349 | if(comfile==file_w32)swapparam(); |
||
3350 | |||
3351 | op66(razr); |
||
3352 | |||
3353 | op(0xD0+reg1); /* CALL reg with stack params */ |
||
3354 | |||
3355 | #ifdef OPTVARCONST |
||
3356 | |||
3357 | #endif |
||
3358 | |||
3359 | } |
||
3360 | |||
3361 | op66(razr); |
||
3362 | |||
3363 | op(0xC0+gstok->number*8); |
||
3364 | |||
3365 | } |
||
3366 | |||
3367 | case tk_seg: |
||
3368 | |||
3369 | op(0x8C); //mov var,SS |
||
3370 | |||
3371 | ClearReg(AX); |
||
3372 | |||
3373 | case tk_string: |
||
3374 | |||
3375 | op(0xB8); |
||
3376 | |||
3377 | if(am32)dwordvalexpected(); |
||
3378 | |||
3379 | } |
||
3380 | |||
3381 | ClearReg(AX); |
||
3382 | |||
3383 | default: valueexpected(); break; |
||
3384 | |||
3385 | if(razr==r32&&cpu<3)cpu=3; |
||
3386 | |||
3387 | |||
3388 | |||
3389 | { |
||
3390 | |||
3391 | unsigned long num; |
||
3392 | |||
3393 | num=li[vop]; |
||
3394 | |||
3395 | if(val |
||
3396 | |||
3397 | return vop; |
||
3398 | |||
3399 | |||
3400 | |||
3401 | { |
||
3402 | |||
3403 | unsigned long long num; |
||
3404 | |||
3405 | num=li[vop]; |
||
3406 | |||
3407 | if(val |
||
3408 | |||
3409 | return vop; |
||
3410 | |||
3411 | |||
3412 | |||
3413 | { |
||
3414 | |||
3415 | int expand=FALSE,rettype; |
||
3416 | |||
3417 | unsigned long holdnumber=0; |
||
3418 | |||
3419 | rettype=(razr==r16?tk_reg:tk_reg32); |
||
3420 | |||
3421 | if(CheckMinusNum()==FALSE){ |
||
3422 | |||
3423 | getoperand(am32==TRUE?EAX:BX); |
||
3424 | |||
3425 | } |
||
3426 | |||
3427 | if(razr==r32){ |
||
3428 | |||
3429 | goto contloop; //оптимизация сложения 32-битных регистров в LEA |
||
3430 | |||
3431 | } |
||
3432 | |||
3433 | goto contloop; //оптимизация сложения 32-битных регистров |
||
3434 | |||
3435 | } |
||
3436 | |||
3437 | otok=tok; |
||
3438 | |||
3439 | #ifdef OPTVARCONST |
||
3440 | |||
3441 | if(tok==tk_number)calcnumber=TRUE; |
||
3442 | |||
3443 | switch(tok){ |
||
3444 | |||
3445 | holdnumber=CalcNumber(sign); |
||
3446 | |||
3447 | else i^=postnumflag; |
||
3448 | |||
3449 | if(tok==tk_mult&&(optimizespeed||razr==r32)&& |
||
3450 | |||
3451 | getoperand(am32==TRUE?EAX:BX); |
||
3452 | |||
3453 | goto loopswitch; |
||
3454 | |||
3455 | if(tok==tk_plus&&tok2==tk_postnumber){ |
||
3456 | |||
3457 | goto loopswitch; |
||
3458 | |||
3459 | MovRegNum(razr,i&f_reloc,holdnumber,EAX); |
||
3460 | |||
3461 | break; |
||
3462 | |||
3463 | op66(razr); |
||
3464 | |||
3465 | AddApiToPost(itok.number); |
||
3466 | |||
3467 | break; |
||
3468 | |||
3469 | case tk_undefofs: |
||
3470 | |||
3471 | op66(razr); |
||
3472 | |||
3473 | next=1; |
||
3474 | |||
3475 | if(tok==tk_undefofs){ |
||
3476 | |||
3477 | // AddUndefOff(0,itok.name); //22.11.04 20:52 |
||
3478 | |||
3479 | } |
||
3480 | |||
3481 | tok=tk_number; |
||
3482 | |||
3483 | if(otok!=tk_postnumber){ |
||
3484 | |||
3485 | else i^=postnumflag; |
||
3486 | |||
3487 | } |
||
3488 | |||
3489 | nexttok(); |
||
3490 | |||
3491 | } |
||
3492 | |||
3493 | next=0; |
||
3494 | |||
3495 | else outdword(holdnumber); |
||
3496 | |||
3497 | break; |
||
3498 | |||
3499 | int reg1,reg2; |
||
3500 | |||
3501 | reg2=am32==FALSE?idxregs[1]:ECX; |
||
3502 | |||
3503 | if(itok.rm||am32==0){ |
||
3504 | |||
3505 | op67(itok.sib==CODE16?r16:r32); |
||
3506 | |||
3507 | outseg(&itok,1); |
||
3508 | |||
3509 | } |
||
3510 | |||
3511 | if(itok.post==0)outseg(&itok,2); |
||
3512 | |||
3513 | } |
||
3514 | |||
3515 | // op(0x8D); op(itok.rm); |
||
3516 | |||
3517 | if((itok.flag&f_extern)==0){ |
||
3518 | |||
3519 | if(am32&&itok.rm==rm_sib)outptr++; |
||
3520 | |||
3521 | outptr=i; |
||
3522 | |||
3523 | else setwordext(&itok.number); |
||
3524 | |||
3525 | ITOK oitok; |
||
3526 | |||
3527 | tok=tk_number; |
||
3528 | |||
3529 | oitok.number=doconstdwordmath(); |
||
3530 | |||
3531 | outaddress(&oitok); // LEA AX,[rm] |
||
3532 | |||
3533 | } |
||
3534 | |||
3535 | break; |
||
3536 | |||
3537 | getoperand(am32==TRUE?EAX:BX); |
||
3538 | |||
3539 | case tk_ID: |
||
3540 | |||
3541 | case tk_proc: |
||
3542 | |||
3543 | case tk_undefproc: |
||
3544 | |||
3545 | if(itok.flag&f_retproc)rettype=(itok.flag&f_retproc)/256+tk_overflowflag-1; |
||
3546 | |||
3547 | macros(sign!=0?(razr==r16?tk_int:tk_long):(razr==r16?tk_word:tk_dword))==0){ |
||
3548 | |||
3549 | } |
||
3550 | |||
3551 | if(*ofsstr){ |
||
3552 | |||
3553 | *ofsstr=NULL; |
||
3554 | |||
3555 | break; |
||
3556 | |||
3557 | donew(); |
||
3558 | |||
3559 | #ifdef OPTVARCONST |
||
3560 | |||
3561 | #endif |
||
3562 | |||
3563 | free(*ofsstr); |
||
3564 | |||
3565 | } |
||
3566 | |||
3567 | break; |
||
3568 | |||
3569 | SINFO wstr=strinf; |
||
3570 | |||
3571 | char *wbuf=bufrm; |
||
3572 | |||
3573 | strinf.bufstr=NULL; |
||
3574 | |||
3575 | nexttok(); break; |
||
3576 | |||
3577 | contloop: |
||
3578 | |||
3579 | NegReg(razr,EAX); |
||
3580 | |||
3581 | } |
||
3582 | |||
3583 | calcnumber=FALSE; |
||
3584 | |||
3585 | if(next)RegMulNum(AX,holdnumber,razr,sign,&expand,i); |
||
3586 | |||
3587 | if(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){ |
||
3588 | |||
3589 | rettype=(razr==r16?tk_reg:tk_reg32); |
||
3590 | |||
3591 | return rettype; |
||
3592 | |||
3593 | |||
3594 | |||
3595 | { |
||
3596 | |||
3597 | int optnum=FALSE; |
||
3598 | |||
3599 | char *ofsstr=NULL; |
||
3600 | |||
3601 | while(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){ |
||
3602 | |||
3603 | vop=0; |
||
3604 | |||
3605 | // !!! new |
||
3606 | |||
3607 | CheckConstVar3(&tok2,&itok2,razr); |
||
3608 | |||
3609 | #endif |
||
3610 | |||
3611 | if(Reg32ToLea2(EAX))continue; //оптимизация сложения 32-битных регистров в LEA |
||
3612 | |||
3613 | } |
||
3614 | |||
3615 | if(tok2==tk_number)optnum=OptimNum(); |
||
3616 | |||
3617 | switch(tok){ |
||
3618 | |||
3619 | case tk_minus: vop+=0x08; |
||
3620 | |||
3621 | case tk_or: vop+=0x08; |
||
3622 | |||
3623 | if(optnum==FALSE)getoperand(); |
||
3624 | |||
3625 | tok=tk_number; |
||
3626 | |||
3627 | } |
||
3628 | |||
3629 | case tk_number: |
||
3630 | |||
3631 | if(optnumadd(itok.number,0,razr,vop))break; |
||
3632 | |||
3633 | case tk_undefofs: |
||
3634 | |||
3635 | op66(razr); |
||
3636 | |||
3637 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
3638 | |||
3639 | else if((itok.flag&f_reloc)!=0)AddReloc(); |
||
3640 | |||
3641 | setzeroflag=TRUE; |
||
3642 | |||
3643 | case tk_apioffset: |
||
3644 | |||
3645 | op(0x05+vop); |
||
3646 | |||
3647 | setzeroflag=TRUE; |
||
3648 | |||
3649 | case tk_qwordvar: |
||
3650 | |||
3651 | case tk_dwordvar: |
||
3652 | |||
3653 | |||
3654 | |||
3655 | if(razr==r32&&(tok==tk_intvar||tok==tk_wordvar))goto defxor; |
||
3656 | |||
3657 | CheckAllMassiv(bufrm,i,&strinf); |
||
3658 | |||
3659 | outseg(&itok,2); |
||
3660 | |||
3661 | op(itok.rm); |
||
3662 | |||
3663 | setzeroflag=TRUE; |
||
3664 | |||
3665 | case tk_doublevar: |
||
3666 | |||
3667 | case tk_floatvar: |
||
3668 | |||
3669 | itok.number=EDX; |
||
3670 | |||
3671 | goto defreg32; |
||
3672 | |||
3673 | case tk_id: |
||
3674 | |||
3675 | case tk_apiproc: |
||
3676 | |||
3677 | case tk_declare: |
||
3678 | |||
3679 | op(0x50); //push AX |
||
3680 | |||
3681 | oaddstack=addstack; |
||
3682 | |||
3683 | procdo(razr==r16?(sign==0?tk_word:tk_int):(sign==0?tk_dword:tk_long)); |
||
3684 | |||
3685 | addESP-=razr==r16?2:4; |
||
3686 | |||
3687 | op(0x58+EDX); |
||
3688 | |||
3689 | warningreg(regs[razr/2-1][EDX]); |
||
3690 | |||
3691 | op66(razr); |
||
3692 | |||
3693 | } |
||
3694 | |||
3695 | case tk_bits: |
||
3696 | |||
3697 | i=itok.bit.siz+itok.bit.ofs; |
||
3698 | |||
3699 | if(i<=32)vops=r32; |
||
3700 | |||
3701 | bits2reg(CX,(razr |
||
3702 | |||
3703 | if(vops==r64)vops=r32; |
||
3704 | |||
3705 | goto defreg32; |
||
3706 | |||
3707 | if(razr==r32)goto defxor; |
||
3708 | |||
3709 | defreg32: |
||
3710 | |||
3711 | op(0x01+vop); |
||
3712 | |||
3713 | setzeroflag=TRUE; |
||
3714 | |||
3715 | case tk_rmnumber: |
||
3716 | |||
3717 | case tk_beg: |
||
3718 | |||
3719 | defxor: |
||
3720 | |||
3721 | op66(razr); |
||
3722 | |||
3723 | op(0xC8); /* OPT AX,CX */ |
||
3724 | |||
3725 | next=0; |
||
3726 | |||
3727 | break; |
||
3728 | |||
3729 | } |
||
3730 | |||
3731 | op66(razr); |
||
3732 | |||
3733 | if(oldtok==tk_plus)outword(0x00d2); //adc dx,0 |
||
3734 | |||
3735 | setzeroflag=TRUE; |
||
3736 | |||
3737 | break; |
||
3738 | |||
3739 | case tk_mod: negflag=1-negflag; vop=1; |
||
3740 | |||
3741 | case tk_div: |
||
3742 | |||
3743 | else{ |
||
3744 | |||
3745 | optnum=FALSE; |
||
3746 | |||
3747 | if(tok==tk_number){ |
||
3748 | |||
3749 | itok.number=-itok.number; |
||
3750 | |||
3751 | } |
||
3752 | |||
3753 | DivMod(vop,sign,razr,expand); |
||
3754 | |||
3755 | op66(razr); |
||
3756 | |||
3757 | else op(0x92); //xchg ax,dx |
||
3758 | |||
3759 | next=0; |
||
3760 | |||
3761 | break; |
||
3762 | |||
3763 | case tk_mult: |
||
3764 | |||
3765 | if(optnum==FALSE)getoperand(); |
||
3766 | |||
3767 | tok=tk_number; |
||
3768 | |||
3769 | } |
||
3770 | |||
3771 | itok.number=-itok.number; |
||
3772 | |||
3773 | } |
||
3774 | |||
3775 | case tk_number: |
||
3776 | |||
3777 | break; |
||
3778 | |||
3779 | case tk_longvar: |
||
3780 | |||
3781 | i=2; |
||
3782 | |||
3783 | case tk_wordvar: |
||
3784 | |||
3785 | i+=2; |
||
3786 | |||
3787 | op66(razr); |
||
3788 | |||
3789 | op(0xF7); //imul var |
||
3790 | |||
3791 | else op(0x20+itok.rm); |
||
3792 | |||
3793 | setzeroflag=FALSE; |
||
3794 | |||
3795 | case tk_doublevar: |
||
3796 | |||
3797 | case tk_floatvar: |
||
3798 | |||
3799 | op66(razr); |
||
3800 | |||
3801 | op(0xE8+EDX); // IMUL EDX |
||
3802 | |||
3803 | warningreg(regs[1][EDX]); |
||
3804 | |||
3805 | case tk_ID: |
||
3806 | |||
3807 | case tk_proc: |
||
3808 | |||
3809 | case tk_undefproc: |
||
3810 | |||
3811 | op66(razr); |
||
3812 | |||
3813 | addESP+=razr==r16?2:4; |
||
3814 | |||
3815 | addstack=FALSE; |
||
3816 | |||
3817 | addstack=oaddstack; |
||
3818 | |||
3819 | op66(razr); |
||
3820 | |||
3821 | itok.number=EDX; |
||
3822 | |||
3823 | goto mulreg32; |
||
3824 | |||
3825 | int vops; |
||
3826 | |||
3827 | if(i<=64)vops=r64; |
||
3828 | |||
3829 | if(i<=16)vops=r16; |
||
3830 | |||
3831 | itok.number=CX; |
||
3832 | |||
3833 | warningreg(regs[vops/2-1][ECX]); |
||
3834 | |||
3835 | case tk_reg: |
||
3836 | |||
3837 | if(razr==r32)goto mulreg; |
||
3838 | |||
3839 | mulreg32: |
||
3840 | |||
3841 | op(0xF7); |
||
3842 | |||
3843 | else op(0xE0+(unsigned int)itok.number); |
||
3844 | |||
3845 | break; |
||
3846 | |||
3847 | case tk_undefofs: |
||
3848 | |||
3849 | op(0x69); |
||
3850 | |||
3851 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
3852 | |||
3853 | razr==r16?outword(itok.number):outdword(itok.number); |
||
3854 | |||
3855 | break; |
||
3856 | |||
3857 | op66(razr); |
||
3858 | |||
3859 | op(0xc0); |
||
3860 | |||
3861 | setzeroflag=FALSE; |
||
3862 | |||
3863 | case tk_seg: |
||
3864 | |||
3865 | case tk_beg: |
||
3866 | |||
3867 | case tk_rmnumber: |
||
3868 | |||
3869 | i=EDX; |
||
3870 | |||
3871 | getintoreg_32(i,razr,sign,&ofsstr,FALSE); |
||
3872 | |||
3873 | op(0xF7); |
||
3874 | |||
3875 | else op(0xE0+i); /* MUL i */ |
||
3876 | |||
3877 | setzeroflag=FALSE; |
||
3878 | |||
3879 | if(i!=EDX)warningreg(regs[razr/2-1][i]); |
||
3880 | |||
3881 | default: valueexpected(); break; |
||
3882 | |||
3883 | break; |
||
3884 | |||
3885 | case tk_andminus: vop+=0x18; |
||
3886 | |||
3887 | getoperand(); |
||
3888 | |||
3889 | itok.number=-itok.number; |
||
3890 | |||
3891 | op(0x05+vop); |
||
3892 | |||
3893 | razr==r16?outword((unsigned int)itok.number):outdword(itok.number); |
||
3894 | |||
3895 | else{ |
||
3896 | |||
3897 | NegReg(razr,ECX); |
||
3898 | |||
3899 | op(0x01+vop); /* opt AX,CX */ |
||
3900 | |||
3901 | warningreg(regs[razr/2-1][1]); |
||
3902 | |||
3903 | } |
||
3904 | |||
3905 | break; |
||
3906 | |||
3907 | getoperand(); |
||
3908 | |||
3909 | if(expand==TRUE){ |
||
3910 | |||
3911 | op66(razr); |
||
3912 | |||
3913 | outword(0xC2a4); //SHLD DX,AX,num |
||
3914 | |||
3915 | } |
||
3916 | |||
3917 | if((unsigned int)itok.number==1)outdword(0xd213c001); //ADD AX,AX ADC DX,DX |
||
3918 | |||
3919 | getintobeg(CL,&ofsstr); |
||
3920 | |||
3921 | outword(0xfae2); //LOOP -6 |
||
3922 | |||
3923 | next=0; |
||
3924 | |||
3925 | break; |
||
3926 | |||
3927 | } |
||
3928 | |||
3929 | setzeroflag=TRUE; |
||
3930 | |||
3931 | else goto llminus; |
||
3932 | |||
3933 | case tk_llminus: |
||
3934 | |||
3935 | llminus: |
||
3936 | |||
3937 | getintobeg(CL,&ofsstr); |
||
3938 | |||
3939 | } |
||
3940 | |||
3941 | next=0; |
||
3942 | |||
3943 | if(chip>2||razr==r32){ |
||
3944 | |||
3945 | op(0x0f); |
||
3946 | |||
3947 | } |
||
3948 | |||
3949 | outdword(0xd213c001); //ADD AX,AX ADC DX,DX |
||
3950 | |||
3951 | break; |
||
3952 | |||
3953 | op66(razr); |
||
3954 | |||
3955 | setzeroflag=TRUE; |
||
3956 | |||
3957 | case tk_rr: |
||
3958 | |||
3959 | getoperand(); |
||
3960 | |||
3961 | if(tok==tk_number){ |
||
3962 | |||
3963 | op66(razr); |
||
3964 | |||
3965 | op66(razr); |
||
3966 | |||
3967 | setzeroflag=TRUE; |
||
3968 | |||
3969 | else if((unsigned int)itok.number!=0){ |
||
3970 | |||
3971 | op66(razr); |
||
3972 | |||
3973 | outword(0xd0ac); //shrd ax,dx,num |
||
3974 | |||
3975 | op66(razr); |
||
3976 | |||
3977 | op(itok.number); |
||
3978 | |||
3979 | } |
||
3980 | |||
3981 | next=0; |
||
3982 | |||
3983 | warningreg(begs[1]); |
||
3984 | |||
3985 | outdword(0xfae2d8d1); //rcr ax,1 LOOP -6 |
||
3986 | |||
3987 | } |
||
3988 | |||
3989 | } |
||
3990 | |||
3991 | } |
||
3992 | |||
3993 | RshiftReg(razr,EAX,vop); |
||
3994 | |||
3995 | next=0; |
||
3996 | |||
3997 | break; |
||
3998 | |||
3999 | if(sign)vop=0x10; |
||
4000 | |||
4001 | rrminus: |
||
4002 | |||
4003 | getintobeg(CL,&ofsstr); |
||
4004 | |||
4005 | } |
||
4006 | |||
4007 | if(expand==TRUE){ |
||
4008 | |||
4009 | op66(razr); |
||
4010 | |||
4011 | outword(0xd0ad); //shrd ax,dx,cl |
||
4012 | |||
4013 | op(0xd3); op(0xea+vop);//s?r dx,num |
||
4014 | |||
4015 | } |
||
4016 | |||
4017 | op(0xd1); op(0xea+vop);//s?r dx,1 |
||
4018 | |||
4019 | setzeroflag=FALSE; |
||
4020 | |||
4021 | } |
||
4022 | |||
4023 | op66(razr); |
||
4024 | |||
4025 | setzeroflag=TRUE; |
||
4026 | |||
4027 | next=0; |
||
4028 | |||
4029 | default: operatorexpected(); break; |
||
4030 | |||
4031 | calcnumber=FALSE; |
||
4032 | |||
4033 | if(negflag){ |
||
4034 | |||
4035 | setzeroflag=TRUE; |
||
4036 | |||
4037 | } |
||
4038 | |||
4039 | } |
||
4040 | |||
4041 | ClearReg(EAX); |
||
4042 | |||
4043 | if(razr==r32&&cpu<3)cpu=3; |
||
4044 | |||
4045 | |||
4046 | |||
4047 | { |
||
4048 | |||
4049 | switch(gtok){ |
||
4050 | |||
4051 | int razr; |
||
4052 | |||
4053 | if(i<=64)razr=r64; |
||
4054 | |||
4055 | if(i<=16)razr=r16; |
||
4056 | |||
4057 | bits2reg(AL,razr); |
||
4058 | |||
4059 | case tk_number: |
||
4060 | |||
4061 | op(gstok->number); |
||
4062 | |||
4063 | break; |
||
4064 | |||
4065 | CheckAllMassiv(gbuf,gstok->size,gstr,gstok); |
||
4066 | |||
4067 | op67(gstok->sib==CODE16?r16:r32); |
||
4068 | |||
4069 | op(0x8D); /* LEA AX,[rm] */ |
||
4070 | |||
4071 | if(gstok->post!=0&&gstok->post!=UNDEF_OFSET){ |
||
4072 | |||
4073 | i=outptr; |
||
4074 | |||
4075 | setwordpost(gstok); |
||
4076 | |||
4077 | } |
||
4078 | |||
4079 | } |
||
4080 | |||
4081 | ClearReg(AL); |
||
4082 | |||
4083 | case tk_postnumber: |
||
4084 | |||
4085 | op(0xB8); /* MOV AX,# */ |
||
4086 | |||
4087 | outword(gstok->number); |
||
4088 | |||
4089 | break; |
||
4090 | |||
4091 | if(cpu<3)cpu=3; |
||
4092 | |||
4093 | op66(r32); |
||
4094 | |||
4095 | if(ESPloc&&am32&&gstok->segm==SS)gstok->number+=4; |
||
4096 | |||
4097 | CheckAllMassiv(gbuf,4,gstr,gstok); |
||
4098 | |||
4099 | op(0xd9); |
||
4100 | |||
4101 | outaddress(gstok); |
||
4102 | |||
4103 | op66(r32); |
||
4104 | |||
4105 | addESP-=4; |
||
4106 | |||
4107 | ClearReg(AL); |
||
4108 | |||
4109 | case tk_qwordvar: |
||
4110 | |||
4111 | case tk_longvar: |
||
4112 | |||
4113 | i+=2; |
||
4114 | |||
4115 | case tk_wordvar: |
||
4116 | |||
4117 | case tk_bytevar: |
||
4118 | |||
4119 | i++; |
||
4120 | |||
4121 | outseg(gstok,1); |
||
4122 | |||
4123 | if(gstok->post==UNDEF_OFSET)AddUndefOff(2,gstok->name); |
||
4124 | |||
4125 | else outdword(gstok->number); |
||
4126 | |||
4127 | else{ |
||
4128 | |||
4129 | outseg(gstok,2); |
||
4130 | |||
4131 | op(gstok->rm); |
||
4132 | |||
4133 | } |
||
4134 | |||
4135 | break; |
||
4136 | |||
4137 | if(gstok->number>BX){ |
||
4138 | |||
4139 | if(gstok->number!=AX)op66(r32); |
||
4140 | |||
4141 | goto beg1; |
||
4142 | |||
4143 | if(gstok->number>BX){ |
||
4144 | |||
4145 | if(gstok->number!=AX)op66(r16); |
||
4146 | |||
4147 | case tk_beg: |
||
4148 | |||
4149 | if(gstok->number!=AL){ |
||
4150 | |||
4151 | op(0xC0+gstok->number*8); |
||
4152 | |||
4153 | ClearReg(AL); |
||
4154 | |||
4155 | case tk_seg: |
||
4156 | |||
4157 | op(0x8C); op(0xC0+gstok->number*8); break; |
||
4158 | |||
4159 | default: bytevalexpected(0); break; |
||
4160 | |||
4161 | } |
||
4162 | |||
4163 | int doalmath(int sign,char **ofsstr) |
||
4164 | |||
4165 | int negflag=0,i=0; |
||
4166 | |||
4167 | if(tok==tk_minus){ |
||
4168 | |||
4169 | negflag=1; |
||
4170 | |||
4171 | } |
||
4172 | |||
4173 | #ifdef OPTVARCONST |
||
4174 | |||
4175 | if(CheckConstVar(&itok)){ |
||
4176 | |||
4177 | calcnumber=TRUE; |
||
4178 | |||
4179 | } |
||
4180 | |||
4181 | switch(tok){ |
||
4182 | |||
4183 | op(0xB0); //mov AL,num |
||
4184 | |||
4185 | op(i); |
||
4186 | |||
4187 | break; |
||
4188 | |||
4189 | getoperand(am32==TRUE?EAX:BX); |
||
4190 | |||
4191 | case tk_ID: |
||
4192 | |||
4193 | case tk_proc: |
||
4194 | |||
4195 | case tk_undefproc: |
||
4196 | |||
4197 | if(itok.flag&f_retproc)rettype=(itok.flag&f_retproc)/256+tk_overflowflag-1; |
||
4198 | |||
4199 | nexttok(); |
||
4200 | |||
4201 | free(*ofsstr); |
||
4202 | |||
4203 | } |
||
4204 | |||
4205 | default: |
||
4206 | |||
4207 | strinf.bufstr=NULL; |
||
4208 | |||
4209 | char *bbuf; |
||
4210 | |||
4211 | bbuf=bufrm; |
||
4212 | |||
4213 | getintoal(tok,&btok,bbuf,&bstr); nexttok(); break; |
||
4214 | |||
4215 | #ifdef OPTVARCONST |
||
4216 | |||
4217 | #endif |
||
4218 | |||
4219 | if(optimizespeed&&(chip==5||chip==6))outdword(0xC0FEFF34); //xor AL,-1 AL++ |
||
4220 | |||
4221 | setzeroflag=TRUE; |
||
4222 | |||
4223 | if(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){ |
||
4224 | |||
4225 | rettype=tk_beg; |
||
4226 | |||
4227 | return rettype; |
||
4228 | |||
4229 | |||
4230 | |||
4231 | { |
||
4232 | |||
4233 | int expand=FALSE,optnum=FALSE; |
||
4234 | |||
4235 | char *ofsstr=NULL; |
||
4236 | |||
4237 | vop=0; |
||
4238 | |||
4239 | next=1; |
||
4240 | |||
4241 | if(tok2>=tk_charvar&&tok2<=tk_doublevar&&itok2.npointr==0){ |
||
4242 | |||
4243 | tok2=tk_number; |
||
4244 | |||
4245 | } |
||
4246 | |||
4247 | #endif |
||
4248 | |||
4249 | int oldtok=tok; |
||
4250 | |||
4251 | case tk_xor: vop+=0x08; |
||
4252 | |||
4253 | case tk_and: vop+=0x18; |
||
4254 | |||
4255 | case tk_plus: |
||
4256 | |||
4257 | else{ |
||
4258 | |||
4259 | optnum=FALSE; |
||
4260 | |||
4261 | switch(tok){ |
||
4262 | |||
4263 | if(itok.number==0&&oldtok!=tk_and)break; |
||
4264 | |||
4265 | op(0x04+vop); |
||
4266 | |||
4267 | break; |
||
4268 | |||
4269 | CheckAllMassiv(bufrm,itok.size,&strinf); |
||
4270 | |||
4271 | op67(itok.sib==CODE16?r16:r32); |
||
4272 | |||
4273 | op(0x8D); /* LEA CX,[rm] */ |
||
4274 | |||
4275 | if(itok.post!=0&&itok.post!=UNDEF_OFSET){ |
||
4276 | |||
4277 | unsigned int ooutptr=outptr; |
||
4278 | |||
4279 | setwordpost(&itok); |
||
4280 | |||
4281 | } |
||
4282 | |||
4283 | } |
||
4284 | |||
4285 | op(vop); /* OPT AL,CL */ |
||
4286 | |||
4287 | warningreg(regs[0][1]); |
||
4288 | |||
4289 | case tk_postnumber: |
||
4290 | |||
4291 | op(0x05+vop); /* OPT AX,# */ |
||
4292 | |||
4293 | outword((unsigned int)itok.number); |
||
4294 | |||
4295 | case tk_qwordvar: |
||
4296 | |||
4297 | case tk_longvar: |
||
4298 | |||
4299 | i+=2; |
||
4300 | |||
4301 | case tk_wordvar: |
||
4302 | |||
4303 | case tk_charvar: |
||
4304 | |||
4305 | i++; |
||
4306 | |||
4307 | outseg(&itok,2); |
||
4308 | |||
4309 | outaddress(&itok); |
||
4310 | |||
4311 | case tk_ID: |
||
4312 | |||
4313 | case tk_proc: |
||
4314 | |||
4315 | case tk_undefproc: |
||
4316 | |||
4317 | op66(r16); |
||
4318 | |||
4319 | addESP+=2; |
||
4320 | |||
4321 | oaddstack=addstack; |
||
4322 | |||
4323 | procdo(sign!=0?tk_char:tk_byte); |
||
4324 | |||
4325 | addESP-=2; |
||
4326 | |||
4327 | op(0x58+CX); |
||
4328 | |||
4329 | warningreg(regs[0][CX]); |
||
4330 | |||
4331 | op66(r16); |
||
4332 | |||
4333 | } |
||
4334 | |||
4335 | case tk_bits: |
||
4336 | |||
4337 | i=itok.bit.siz+itok.bit.ofs; |
||
4338 | |||
4339 | if(i<=32)razr=r32; |
||
4340 | |||
4341 | if(i<=8)razr=r8; |
||
4342 | |||
4343 | itok.number=CL; |
||
4344 | |||
4345 | warningreg(razr==r8?begs[1]:(regs[razr/2-1][1])); |
||
4346 | |||
4347 | case tk_doublevar: |
||
4348 | |||
4349 | case tk_floatvar: |
||
4350 | |||
4351 | itok.number=0; |
||
4352 | |||
4353 | defbeg: |
||
4354 | |||
4355 | op(0xC0+(unsigned int)itok.number*8); |
||
4356 | |||
4357 | case tk_reg32: |
||
4358 | |||
4359 | if((unsigned int)itok.number>BX){ |
||
4360 | |||
4361 | op(0x89); /* MOV CX,reg */ |
||
4362 | |||
4363 | op(0xC1+(unsigned int)itok.number*8); /* MOV instr */ |
||
4364 | |||
4365 | } |
||
4366 | |||
4367 | default: valueexpected(); break; |
||
4368 | |||
4369 | setzeroflag=TRUE; |
||
4370 | |||
4371 | if(oldtok==tk_plus){ |
||
4372 | |||
4373 | op(0); |
||
4374 | |||
4375 | else if(oldtok==tk_minus){ |
||
4376 | |||
4377 | op(0); |
||
4378 | |||
4379 | setzeroflag=FALSE; |
||
4380 | |||
4381 | break; |
||
4382 | |||
4383 | case tk_mod: negflag=1-negflag; vop=1; |
||
4384 | |||
4385 | case tk_div: |
||
4386 | |||
4387 | else{ |
||
4388 | |||
4389 | optnum=FALSE; |
||
4390 | |||
4391 | if(tok==tk_number){ |
||
4392 | |||
4393 | itok.number=-itok.number; |
||
4394 | |||
4395 | } |
||
4396 | |||
4397 | if(vop){ //% |
||
4398 | |||
4399 | if(caselong(itok.number)!=NUMNUM){ |
||
4400 | |||
4401 | op((unsigned int)itok.number-1); |
||
4402 | |||
4403 | } |
||
4404 | |||
4405 | if(expand==FALSE){ |
||
4406 | |||
4407 | else xorAHAH(); |
||
4408 | |||
4409 | op(0xB1); op((unsigned int)itok.number); /* MOV CL,# */ |
||
4410 | |||
4411 | else outword(0xF1F6); /* DIV CL */ |
||
4412 | |||
4413 | setzeroflag=FALSE; |
||
4414 | |||
4415 | break; |
||
4416 | |||
4417 | } |
||
4418 | |||
4419 | switch((unsigned int)itok.number){ |
||
4420 | |||
4421 | DevideZero(); |
||
4422 | |||
4423 | case 1: break; |
||
4424 | |||
4425 | op(0xd0+expand); |
||
4426 | |||
4427 | else op(0xE8);// SHR AL,1 |
||
4428 | |||
4429 | break; |
||
4430 | |||
4431 | vop=caselong(itok.number); |
||
4432 | |||
4433 | if(chip<2){ |
||
4434 | |||
4435 | op(0xd2+expand); |
||
4436 | |||
4437 | else op(0xE8); // SHR AL,CL |
||
4438 | |||
4439 | } |
||
4440 | |||
4441 | op(0xc0+expand); |
||
4442 | |||
4443 | else op(0xE8); /* SHR AL,num */ |
||
4444 | |||
4445 | if(cpu<2)cpu=2; |
||
4446 | |||
4447 | setzeroflag=TRUE; |
||
4448 | |||
4449 | else{ |
||
4450 | |||
4451 | if(optimizespeed&&(itok.flag&f_reloc)==0&&sign==0){ //for signed needed new algoritm |
||
4452 | |||
4453 | itok.number=256/(unsigned int)itok.number+1; |
||
4454 | |||
4455 | xorAHAH(); |
||
4456 | |||
4457 | outword(0xC06B); //imul AX,num |
||
4458 | |||
4459 | warningreg(regs[0][2]); |
||
4460 | |||
4461 | else{ |
||
4462 | |||
4463 | op(itok.number); |
||
4464 | |||
4465 | warningreg(begs[2]); |
||
4466 | |||
4467 | outword(0xE088); //mov AL.AH |
||
4468 | |||
4469 | break; |
||
4470 | |||
4471 | if(sign)cbw(); |
||
4472 | |||
4473 | } |
||
4474 | |||
4475 | op((unsigned int)itok.number); |
||
4476 | |||
4477 | else outword(0xF1F6); /* DIV CL */ |
||
4478 | |||
4479 | warningreg(begs[1]); |
||
4480 | |||
4481 | } |
||
4482 | |||
4483 | } |
||
4484 | |||
4485 | case tk_doublevar: |
||
4486 | |||
4487 | if(tok==tk_floatvar){ |
||
4488 | |||
4489 | itok.number=ECX; |
||
4490 | |||
4491 | sign=1; |
||
4492 | |||
4493 | if(expand==FALSE){ |
||
4494 | |||
4495 | else xorAHAH(); |
||
4496 | |||
4497 | switch(tok){ |
||
4498 | |||
4499 | case tk_postnumber: |
||
4500 | |||
4501 | if(sign)outword(0xF9F6); // IDIV CL |
||
4502 | |||
4503 | setzeroflag=FALSE; |
||
4504 | |||
4505 | break; |
||
4506 | |||
4507 | i=4; |
||
4508 | |||
4509 | case tk_dwordvar: |
||
4510 | |||
4511 | case tk_intvar: |
||
4512 | |||
4513 | i++; |
||
4514 | |||
4515 | case tk_bytevar: |
||
4516 | |||
4517 | CheckAllMassiv(bufrm,i,&strinf); |
||
4518 | |||
4519 | op(0xF6); |
||
4520 | |||
4521 | else op(0x30+itok.rm); |
||
4522 | |||
4523 | setzeroflag=FALSE; |
||
4524 | |||
4525 | case tk_bits: |
||
4526 | |||
4527 | i=itok.bit.siz+itok.bit.ofs; |
||
4528 | |||
4529 | if(i<=32)razr=r32; |
||
4530 | |||
4531 | if(i<=8)razr=r8; |
||
4532 | |||
4533 | itok.number=CL; |
||
4534 | |||
4535 | warningreg(razr==r8?begs[1]:(regs[razr/2-1][1])); |
||
4536 | |||
4537 | case tk_ID: |
||
4538 | |||
4539 | case tk_proc: |
||
4540 | |||
4541 | case tk_undefproc: |
||
4542 | |||
4543 | op66(r16); |
||
4544 | |||
4545 | addESP+=2; |
||
4546 | |||
4547 | oaddstack=addstack; |
||
4548 | |||
4549 | procdo(sign!=0?tk_char:tk_byte); |
||
4550 | |||
4551 | addESP-=2; |
||
4552 | |||
4553 | op(0x58+CX); |
||
4554 | |||
4555 | warningreg(regs[0][CX]); |
||
4556 | |||
4557 | op(0x90+CX); //xchg ax,cx |
||
4558 | |||
4559 | defdiv: |
||
4560 | |||
4561 | if(sign)op(0xF8+(unsigned int)itok.number); |
||
4562 | |||
4563 | setzeroflag=FALSE; |
||
4564 | |||
4565 | case tk_reg32: |
||
4566 | |||
4567 | if((unsigned int)itok.number>BX){ |
||
4568 | |||
4569 | op(0x89); /* MOV CX,reg */ |
||
4570 | |||
4571 | op(0xC1+(unsigned int)itok.number*8); /* MOV instr */ |
||
4572 | |||
4573 | } |
||
4574 | |||
4575 | default: valueexpected(); break; |
||
4576 | |||
4577 | if(vop)outword(0xE088);// MOV AL,AH |
||
4578 | |||
4579 | expand=FALSE; |
||
4580 | |||
4581 | case tk_multminus: negflag=1; |
||
4582 | |||
4583 | expand=expandvar(); |
||
4584 | |||
4585 | else{ |
||
4586 | |||
4587 | optnum=FALSE; |
||
4588 | |||
4589 | switch(tok){ |
||
4590 | |||
4591 | if(negflag){ |
||
4592 | |||
4593 | negflag=0; |
||
4594 | |||
4595 | itok.number&=255; |
||
4596 | |||
4597 | case 0: /* AL * 0 = MOV AL,0 */ |
||
4598 | |||
4599 | case 1: |
||
4600 | |||
4601 | setzeroflag=FALSE; |
||
4602 | |||
4603 | case 2: |
||
4604 | |||
4605 | if(sign)cbw(); |
||
4606 | |||
4607 | } |
||
4608 | |||
4609 | setzeroflag=TRUE; |
||
4610 | |||
4611 | default: |
||
4612 | |||
4613 | if(vop!=NUMNUM){ |
||
4614 | |||
4615 | if(expand==TRUE){ |
||
4616 | |||
4617 | if(sign)cbw(); |
||
4618 | |||
4619 | } |
||
4620 | |||
4621 | outword(0xE0D2+expand);// SHL AL,CL |
||
4622 | |||
4623 | } |
||
4624 | |||
4625 | if(expand==TRUE){ |
||
4626 | |||
4627 | if(sign)cbw(); |
||
4628 | |||
4629 | op66(r16); |
||
4630 | |||
4631 | outword(0xe0c0+expand); //SHL AX/L,num |
||
4632 | |||
4633 | if(cpu<1)cpu=1; |
||
4634 | |||
4635 | setzeroflag=TRUE; |
||
4636 | |||
4637 | else if(expand==FALSE&&optimizespeed!=FALSE&& |
||
4638 | |||
4639 | else{ |
||
4640 | |||
4641 | op(0xB1); /* MOV CL,# */ |
||
4642 | |||
4643 | if(sign)outword(0xE9F6);// IMUL CL |
||
4644 | |||
4645 | setzeroflag=FALSE; |
||
4646 | |||
4647 | } |
||
4648 | |||
4649 | break; |
||
4650 | |||
4651 | case tk_postnumber: |
||
4652 | |||
4653 | if(sign)outword(0xE9F6); // IMUL CL |
||
4654 | |||
4655 | setzeroflag=FALSE; |
||
4656 | |||
4657 | break; |
||
4658 | |||
4659 | i=4; |
||
4660 | |||
4661 | Float2reg32(ECX,i); |
||
4662 | |||
4663 | outword(0xE9F6); // IMUL CL |
||
4664 | |||
4665 | warningreg(begs[1]); |
||
4666 | |||
4667 | case tk_qwordvar: |
||
4668 | |||
4669 | case tk_longvar: |
||
4670 | |||
4671 | i+=2; |
||
4672 | |||
4673 | case tk_wordvar: |
||
4674 | |||
4675 | case tk_charvar: |
||
4676 | |||
4677 | i++; |
||
4678 | |||
4679 | outseg(&itok,2); |
||
4680 | |||
4681 | if(sign)op(0x28+itok.rm); |
||
4682 | |||
4683 | outaddress(&itok); |
||
4684 | |||
4685 | break; |
||
4686 | |||
4687 | int razr; |
||
4688 | |||
4689 | if(i<=64)razr=r64; |
||
4690 | |||
4691 | if(i<=16)razr=r16; |
||
4692 | |||
4693 | bits2reg(CL,razr); |
||
4694 | |||
4695 | if(razr==r64)razr=r32; |
||
4696 | |||
4697 | goto defmul; |
||
4698 | |||
4699 | case tk_id: |
||
4700 | |||
4701 | case tk_apiproc: |
||
4702 | |||
4703 | case tk_declare: |
||
4704 | |||
4705 | op(0x50); //push AX |
||
4706 | |||
4707 | unsigned char oaddstack; |
||
4708 | |||
4709 | addstack=FALSE; |
||
4710 | |||
4711 | addstack=oaddstack; |
||
4712 | |||
4713 | op66(r16); |
||
4714 | |||
4715 | itok.number=DX; |
||
4716 | |||
4717 | case tk_beg: |
||
4718 | |||
4719 | op(0xF6); |
||
4720 | |||
4721 | else op(0xE0+(unsigned int)itok.number); |
||
4722 | |||
4723 | break; |
||
4724 | |||
4725 | case tk_reg: |
||
4726 | |||
4727 | op66(r16); |
||
4728 | |||
4729 | warningreg(regs[0][1]); |
||
4730 | |||
4731 | itok.number=CL; |
||
4732 | |||
4733 | goto defmul; |
||
4734 | |||
4735 | } |
||
4736 | |||
4737 | case tk_xorminus: vop+=0x10; |
||
4738 | |||
4739 | case tk_orminus: vop+=0x08; |
||
4740 | |||
4741 | if(tok==tk_number){ |
||
4742 | |||
4743 | op(0x04+vop); |
||
4744 | |||
4745 | } |
||
4746 | |||
4747 | getintobeg(CL,&ofsstr); |
||
4748 | |||
4749 | op(0x80); |
||
4750 | |||
4751 | } |
||
4752 | |||
4753 | op(0x00+vop); |
||
4754 | |||
4755 | warningreg(begs[1]); |
||
4756 | |||
4757 | } |
||
4758 | |||
4759 | break; |
||
4760 | |||
4761 | vop=8; |
||
4762 | |||
4763 | case tk_ll: |
||
4764 | |||
4765 | if(tok==tk_number){ |
||
4766 | |||
4767 | if(expand==TRUE)op66(r16); |
||
4768 | |||
4769 | } |
||
4770 | |||
4771 | if(chip<2) goto llminus; |
||
4772 | |||
4773 | if(expand==TRUE)op66(r16); |
||
4774 | |||
4775 | op((unsigned int)itok.number); |
||
4776 | |||
4777 | } |
||
4778 | |||
4779 | setzeroflag=TRUE; |
||
4780 | |||
4781 | else goto llminus; |
||
4782 | |||
4783 | case tk_rrminus: |
||
4784 | |||
4785 | if(sign)vop+=0x10; |
||
4786 | |||
4787 | tok=tk_minus; // need 286+ opt some time |
||
4788 | |||
4789 | if(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==1)){ |
||
4790 | |||
4791 | warningreg(begs[1]); |
||
4792 | |||
4793 | else getoperand(); |
||
4794 | |||
4795 | op(0xD2+expand); op(0xE0+vop); |
||
4796 | |||
4797 | next=0; |
||
4798 | |||
4799 | default: operatorexpected(); break; |
||
4800 | |||
4801 | if(negflag){ |
||
4802 | |||
4803 | else outword(0xD8F6);// NEG AL |
||
4804 | |||
4805 | setzeroflag=TRUE; |
||
4806 | |||
4807 | if(next)nexttok(); |
||
4808 | |||
4809 | } |
||
4810 | |||
4811 | calcnumber=FALSE; |
||
4812 | |||
4813 | if(tok==tk_eof)unexpectedeof(); |
||
4814 | |||
4815 | |||
4816 | |||
4817 | |||
4818 | |||
4819 | { |
||
4820 | |||
4821 | int vop=0,sign=0; |
||
4822 | |||
4823 | int reg1=idxregs[0],reg2=idxregs[1]; |
||
4824 | |||
4825 | int rettype=tk_reg; |
||
4826 | |||
4827 | int numpointr=0; |
||
4828 | |||
4829 | if(reg==reg1){ |
||
4830 | |||
4831 | reg2=idxregs[2]; |
||
4832 | |||
4833 | if(reg==reg2)reg2=idxregs[2]; |
||
4834 | |||
4835 | rrettype=razr==r16?tk_word:tk_dword; |
||
4836 | |||
4837 | switch(tok){ |
||
4838 | |||
4839 | if(am32)idxregs[4]=reg; |
||
4840 | |||
4841 | ofsstr=GetLecsem(terminater); |
||
4842 | |||
4843 | else{ |
||
4844 | |||
4845 | switch(tok){ |
||
4846 | |||
4847 | i=r8; |
||
4848 | |||
4849 | case tk_reg: |
||
4850 | |||
4851 | break; |
||
4852 | |||
4853 | i=r32; |
||
4854 | |||
4855 | } |
||
4856 | |||
4857 | waralreadinitreg(regs[razr/4][itok.number],regs[razr/4][reg]); |
||
4858 | |||
4859 | break; |
||
4860 | |||
4861 | if(ofsstr){ |
||
4862 | |||
4863 | if((retreg=CheckIDZReg(ofsstr,reg,razr))!=NOINREG){ |
||
4864 | |||
4865 | if(razr==r16)tok=tk_reg; |
||
4866 | |||
4867 | itok.number=retreg==SKIPREG?reg:retreg; |
||
4868 | |||
4869 | } |
||
4870 | |||
4871 | nexttok(); |
||
4872 | |||
4873 | if(rrettype==tk_float||rrettype==tk_double){ |
||
4874 | |||
4875 | doeaxfloatmath(tk_reg32,reg,rrettype==tk_float?0:4); |
||
4876 | |||
4877 | if(ofsstr){ |
||
4878 | |||
4879 | free(ofsstr); |
||
4880 | |||
4881 | break; |
||
4882 | |||
4883 | while(tok==tk_mult){ |
||
4884 | |||
4885 | numpointr++; |
||
4886 | |||
4887 | if(numpointr>itok.npointr)unuseableinput(); |
||
4888 | |||
4889 | int hnumber=MultiAssign(razr,USEALLREG,numpointr); |
||
4890 | |||
4891 | if(ofsstr){ |
||
4892 | |||
4893 | ofsstr=NULL; |
||
4894 | |||
4895 | if(reg!=hnumber){ |
||
4896 | |||
4897 | op(0x89); |
||
4898 | |||
4899 | } |
||
4900 | |||
4901 | /* if(ofsstr){ |
||
4902 | |||
4903 | free(ofsstr); |
||
4904 | |||
4905 | if(am32)idxregs[4]=255; |
||
4906 | |||
4907 | } |
||
4908 | |||
4909 | if(tok==tk_pointer)cpointr(am32==TRUE?reg:BX,numpointr); |
||
4910 | |||
4911 | if(tok==tk_new)donew(); |
||
4912 | |||
4913 | dodelete(); |
||
4914 | |||
4915 | } |
||
4916 | |||
4917 | if(reg!=AX){ |
||
4918 | |||
4919 | } |
||
4920 | |||
4921 | #ifdef OPTVARCONST |
||
4922 | |||
4923 | #endif |
||
4924 | |||
4925 | free(ofsstr); |
||
4926 | |||
4927 | } |
||
4928 | |||
4929 | } |
||
4930 | |||
4931 | |||
4932 | |||
4933 | if(rrettype==tk_char||rrettype==tk_byte)rettype=doalmath(sign,&ofsstr); |
||
4934 | |||
4935 | else rettype=do_e_axmath(sign,r32,&ofsstr); |
||
4936 | |||
4937 | } |
||
4938 | |||
4939 | if(rrettype==tk_char||rrettype==tk_byte&®<=BX){ |
||
4940 | |||
4941 | if(itok.type!=tp_stopper&&tok!=tk_eof){ |
||
4942 | |||
4943 | rettype=tk_beg; |
||
4944 | |||
4945 | op66(razr); |
||
4946 | |||
4947 | if(!sign)op(0xB6); |
||
4948 | |||
4949 | op(0xC0+reg*9); |
||
4950 | |||
4951 | else{ |
||
4952 | |||
4953 | else next=r32; |
||
4954 | |||
4955 | if(next==r16&&razr==r32){ |
||
4956 | |||
4957 | |||
4958 | |||
4959 | else op(0xBF); |
||
4960 | |||
4961 | } |
||
4962 | |||
4963 | } |
||
4964 | |||
4965 | if(ofsstr){ |
||
4966 | |||
4967 | free(ofsstr); |
||
4968 | |||
4969 | break; |
||
4970 | |||
4971 | ClearReg(reg); |
||
4972 | |||
4973 | case tk_minusminus: op66(razr); op(0x48+reg); |
||
4974 | |||
4975 | break; |
||
4976 | |||
4977 | case tk_pascal: |
||
4978 | |||
4979 | case tk_stdcall: |
||
4980 | |||
4981 | nexttok(); |
||
4982 | |||
4983 | expected('('); |
||
4984 | |||
4985 | } |
||
4986 | |||
4987 | param[0]=0; |
||
4988 | |||
4989 | switch ( vop ) { |
||
4990 | |||
4991 | case tk_stdcall: |
||
4992 | |||
4993 | break; |
||
4994 | |||
4995 | doparams(); |
||
4996 | |||
4997 | case tk_fastcall: |
||
4998 | |||
4999 | break; |
||
5000 | |||
5001 | if(comfile==file_w32)swapparam(); |
||
5002 | |||
5003 | } |
||
5004 | |||
5005 | op66(razr); |
||
5006 | |||
5007 | op(0xD0+reg); /* CALL reg with stack params */ |
||
5008 | |||
5009 | clearregstat(); |
||
5010 | |||
5011 | FreeGlobalConst(); |
||
5012 | |||
5013 | break; |
||
5014 | |||
5015 | getoperand(reg==BX?SI:BX); |
||
5016 | |||
5017 | case tk_qwordvar: |
||
5018 | |||
5019 | case tk_dwordvar: |
||
5020 | |||
5021 | i=4; |
||
5022 | |||
5023 | case tk_intvar: |
||
5024 | |||
5025 | i=2; |
||
5026 | |||
5027 | swapint: |
||
5028 | |||
5029 | CheckAllMassiv(bufrm,i,&strinf,&itok,reg1,reg2); |
||
5030 | |||
5031 | outseg(&itok,2); |
||
5032 | |||
5033 | op(reg*8+itok.rm); |
||
5034 | |||
5035 | break; |
||
5036 | |||
5037 | if(razr==r16)swaperror(); |
||
5038 | |||
5039 | case tk_reg: |
||
5040 | |||
5041 | swapreg: |
||
5042 | |||
5043 | if(RegSwapReg(reg,itok.number,razr)==NOINREG){; |
||
5044 | |||
5045 | if(reg==AX)op(0x90+(unsigned int)itok.number); |
||
5046 | |||
5047 | else{ |
||
5048 | |||
5049 | op(0xC0+(unsigned int)itok.number+reg*8); |
||
5050 | |||
5051 | } |
||
5052 | |||
5053 | } |
||
5054 | |||
5055 | default: swaperror(); break; |
||
5056 | |||
5057 | break; |
||
5058 | |||
5059 | case tk_minusequals: vop+=0x08; |
||
5060 | |||
5061 | case tk_orequals: vop+=0x08; |
||
5062 | |||
5063 | ClearReg(reg); |
||
5064 | |||
5065 | if(RegEqualToLea(reg)){ |
||
5066 | |||
5067 | break; |
||
5068 | |||
5069 | } |
||
5070 | |||
5071 | inptr2--; |
||
5072 | |||
5073 | if(tok==tk_plusequals)tok=tk_plus; |
||
5074 | |||
5075 | if(reg==EAX)do_e_axmath2(0,razr,0); |
||
5076 | |||
5077 | next=0; |
||
5078 | |||
5079 | } |
||
5080 | |||
5081 | if(itok2.type==tp_opperand&&tok!=tk_number&&tok!=tk_undefofs&&tok!=tk_postnumber)goto defadd; |
||
5082 | |||
5083 | idrec *rrec; |
||
5084 | |||
5085 | i=tok; |
||
5086 | |||
5087 | case tk_postnumber: |
||
5088 | |||
5089 | ii=itok.number; |
||
5090 | |||
5091 | opost=itok.post; |
||
5092 | |||
5093 | strcpy(uname,itok.name); |
||
5094 | |||
5095 | tok=tk_number; |
||
5096 | |||
5097 | ii=doconstdwordmath(); |
||
5098 | |||
5099 | if(itok.type==tp_opperand){ |
||
5100 | |||
5101 | sign=ECX; |
||
5102 | |||
5103 | warningreg(regs[razr/2-1][sign]); |
||
5104 | |||
5105 | if(i==tk_postnumber||i==tk_undefofs){ |
||
5106 | |||
5107 | op(0xB8+reg); // MOV reg,# |
||
5108 | |||
5109 | else{ |
||
5110 | |||
5111 | if(i==tk_undefofs)AddUndefOff(2,uname); |
||
5112 | |||
5113 | razr==r16?outword(ii):outdword(ii); |
||
5114 | |||
5115 | else MovRegNum(razr,postnumflag&f_reloc,ii,sign); |
||
5116 | |||
5117 | else doregmath_32(sign,razr,0,&ofsstr); |
||
5118 | |||
5119 | goto addreg; |
||
5120 | |||
5121 | if((postnumflag&f_reloc)==0&&i!=tk_undefofs&&i!=tk_postnumber&&optnumadd(ii,reg,razr,vop))break; |
||
5122 | |||
5123 | op66(razr); |
||
5124 | |||
5125 | else{ |
||
5126 | |||
5127 | op(0xC0+vop+reg); |
||
5128 | |||
5129 | itok.rec=rrec; |
||
5130 | |||
5131 | if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii); |
||
5132 | |||
5133 | if((postnumflag&f_reloc)!=0)AddReloc(); |
||
5134 | |||
5135 | } |
||
5136 | |||
5137 | break; |
||
5138 | |||
5139 | case tk_longvar: |
||
5140 | |||
5141 | i=4; |
||
5142 | |||
5143 | case tk_intvar: |
||
5144 | |||
5145 | i=2; |
||
5146 | |||
5147 | wordadd: |
||
5148 | |||
5149 | op66(razr); |
||
5150 | |||
5151 | op(0x03+vop); |
||
5152 | |||
5153 | outaddress(&itok); |
||
5154 | |||
5155 | case tk_reg: |
||
5156 | |||
5157 | case tk_reg32: |
||
5158 | |||
5159 | op66(razr); |
||
5160 | |||
5161 | op(0xC0+reg+(unsigned int)itok.number*8); |
||
5162 | |||
5163 | case tk_ID: |
||
5164 | |||
5165 | case tk_proc: |
||
5166 | |||
5167 | case tk_undefproc: |
||
5168 | |||
5169 | unsigned char oaddstack; |
||
5170 | |||
5171 | op66(razr); |
||
5172 | |||
5173 | addESP+=razr==r16?2:4; |
||
5174 | |||
5175 | oaddstack=addstack; |
||
5176 | |||
5177 | } |
||
5178 | |||
5179 | if(itok2.type==tp_opperand){ |
||
5180 | |||
5181 | do_e_axmath2(0,razr,0); |
||
5182 | |||
5183 | } |
||
5184 | |||
5185 | addstack=oaddstack; |
||
5186 | |||
5187 | op66(razr); |
||
5188 | |||
5189 | if(vop>0x20){ |
||
5190 | |||
5191 | op(0x90+EDX); //xchg ax,dx |
||
5192 | |||
5193 | op66(razr); |
||
5194 | |||
5195 | op(0xc0+EDX*8); //add ax,dx |
||
5196 | |||
5197 | else{ |
||
5198 | |||
5199 | op(0x01+vop); |
||
5200 | |||
5201 | } |
||
5202 | |||
5203 | case tk_seg: |
||
5204 | |||
5205 | case tk_bytevar: |
||
5206 | |||
5207 | case tk_beg: |
||
5208 | |||
5209 | if(reg==AX){ |
||
5210 | |||
5211 | doregmath_32(ECX,razr,sign,&ofsstr); |
||
5212 | |||
5213 | } |
||
5214 | |||
5215 | do_e_axmath(0,razr,&ofsstr); |
||
5216 | |||
5217 | } |
||
5218 | |||
5219 | op66(razr);// OPT reg32,ECX |
||
5220 | |||
5221 | op(0xC0+reg+sign*8); |
||
5222 | |||
5223 | break; |
||
5224 | |||
5225 | } |
||
5226 | |||
5227 | case tk_rrequals: vop+=0x08; |
||
5228 | |||
5229 | ClearReg(reg); |
||
5230 | |||
5231 | CheckMinusNum(); |
||
5232 | |||
5233 | ii=doconstlongmath(); |
||
5234 | |||
5235 | if(itok.type==tp_opperand){ |
||
5236 | |||
5237 | op(0xB0+CL); op(ii); //mov CL,num |
||
5238 | |||
5239 | warningreg(begs[1]); |
||
5240 | |||
5241 | goto shiftcl; |
||
5242 | |||
5243 | if(ii==1){ |
||
5244 | |||
5245 | op(0xD1); op(0xE0+reg+vop); |
||
5246 | |||
5247 | else if(ii!=0){ |
||
5248 | |||
5249 | op(0xB0+CL); op(ii); //mov CL,num |
||
5250 | |||
5251 | ConstToReg(ii,CL,r8); |
||
5252 | |||
5253 | } |
||
5254 | |||
5255 | op66(razr); |
||
5256 | |||
5257 | op(ii); |
||
5258 | |||
5259 | } |
||
5260 | |||
5261 | } |
||
5262 | |||
5263 | if(!(itok2.type==tp_stopper&&(tok==tk_beg||tok==reg||tok==tk_reg32)&&itok.number==CL)){ |
||
5264 | |||
5265 | dobegmath(CL); |
||
5266 | |||
5267 | ClearReg(CL); |
||
5268 | |||
5269 | } |
||
5270 | |||
5271 | op66(razr); |
||
5272 | |||
5273 | } |
||
5274 | |||
5275 | break; |
||
5276 | |||
5277 | ClearReg(reg); |
||
5278 | |||
5279 | |||
5280 | |||
5281 | ii=doconstlongmath(); |
||
5282 | |||
5283 | if(itok.type==tp_opperand){ |
||
5284 | |||
5285 | MovRegNum(razr,postnumflag&f_reloc,ii,sign); |
||
5286 | |||
5287 | else doregmath_32(ECX,razr,0,&ofsstr); |
||
5288 | |||
5289 | goto mulreg; |
||
5290 | |||
5291 | i=0; |
||
5292 | |||
5293 | } |
||
5294 | |||
5295 | if(itok2.type==tp_stopper)next=(unsigned char)MulReg(reg,razr); |
||
5296 | |||
5297 | if(reg==AX){ |
||
5298 | |||
5299 | doregmath_32(ECX,razr,sign,&ofsstr); |
||
5300 | |||
5301 | } |
||
5302 | |||
5303 | do_e_axmath(0,razr,&ofsstr); |
||
5304 | |||
5305 | } |
||
5306 | |||
5307 | warningreg(regs[razr/2-1][sign]); |
||
5308 | |||
5309 | op66(razr); |
||
5310 | |||
5311 | op(0xC0+reg*8+sign); |
||
5312 | |||
5313 | } |
||
5314 | |||
5315 | break; |
||
5316 | |||
5317 | getoperand(reg==BX?SI:BX); |
||
5318 | |||
5319 | CheckMinusNum(); |
||
5320 | |||
5321 | ii=doconstlongmath(); |
||
5322 | |||
5323 | if(itok.type==tp_opperand){ |
||
5324 | |||
5325 | op(0x50+reg); //push reg |
||
5326 | |||
5327 | MovRegNum(razr,postnumflag&f_reloc,ii,EAX); |
||
5328 | |||
5329 | ClearReg(AX); |
||
5330 | |||
5331 | } |
||
5332 | |||
5333 | if(vop!=0){ |
||
5334 | |||
5335 | op(0xB1); op(vop); /* MOV CL,num */ |
||
5336 | |||
5337 | op(0xE8+reg); // SHR reg,CL |
||
5338 | |||
5339 | ClearReg(CX); |
||
5340 | |||
5341 | else{ |
||
5342 | |||
5343 | op(0xC1); |
||
5344 | |||
5345 | op(vop); |
||
5346 | |||
5347 | } |
||
5348 | |||
5349 | else{ |
||
5350 | |||
5351 | op66(razr); |
||
5352 | |||
5353 | } |
||
5354 | |||
5355 | if(reg!=EAX){ |
||
5356 | |||
5357 | op(0x90+reg); //xchg reg,AX |
||
5358 | |||
5359 | ClearReg(AX); |
||
5360 | |||
5361 | } |
||
5362 | |||
5363 | else if(itok2.type==tp_stopper){ |
||
5364 | |||
5365 | op66(razr); |
||
5366 | |||
5367 | } |
||
5368 | |||
5369 | next=0; |
||
5370 | |||
5371 | op66(razr); |
||
5372 | |||
5373 | warningreg(regs[razr/2-1][EAX]); |
||
5374 | |||
5375 | } |
||
5376 | |||
5377 | else{ |
||
5378 | |||
5379 | op(0x50+reg); //push reg |
||
5380 | |||
5381 | do_e_axmath(0,razr,&ofsstr); |
||
5382 | |||
5383 | op66(razr); |
||
5384 | |||
5385 | if(reg==EAX){ |
||
5386 | |||
5387 | warningreg(regs[razr/2-1][ECX]); |
||
5388 | |||
5389 | } |
||
5390 | |||
5391 | op(0x58+sign); //pop sign |
||
5392 | |||
5393 | op(0x90+sign); //xchg AX,sign |
||
5394 | |||
5395 | op(0xF7); |
||
5396 | |||
5397 | op66(razr); |
||
5398 | |||
5399 | if(optimizespeed){ |
||
5400 | |||
5401 | op(0xC0+reg); //mov reg,AX |
||
5402 | |||
5403 | else op(0x90+reg); //xchg AX,sign |
||
5404 | |||
5405 | warningreg(regs[razr/2-1][EAX]); |
||
5406 | |||
5407 | next=0; |
||
5408 | |||
5409 | break; |
||
5410 | |||
5411 | } |
||
5412 | |||
5413 | if(terminater==tk_semicolon)seminext(); |
||
5414 | |||
5415 | // puts("return doreg_32"); |
||
5416 | |||
5417 | } |
||
5418 | |||
5419 | int optnumadd(unsigned long num,int reg,int razr,int vop) |
||
5420 | |||
5421 | int nrazr=0; |
||
5422 | |||
5423 | if(vop==0x20){ //&= |
||
5424 | |||
5425 | setzeroflag=TRUE; |
||
5426 | |||
5427 | return TRUE; //+= -= |= ^= |
||
5428 | |||
5429 | if(vop==8){ //|= |
||
5430 | |||
5431 | if((unsigned short)num<256&&razr==r16&®<4){ |
||
5432 | |||
5433 | else{ |
||
5434 | |||
5435 | op(0xc8+reg); |
||
5436 | |||
5437 | op(num); |
||
5438 | |||
5439 | } |
||
5440 | |||
5441 | op66(r16); |
||
5442 | |||
5443 | else{ |
||
5444 | |||
5445 | op(0xc8+reg); |
||
5446 | |||
5447 | outword(num); |
||
5448 | |||
5449 | } |
||
5450 | |||
5451 | if(num==1){ |
||
5452 | |||
5453 | op66(razr); |
||
5454 | |||
5455 | setzeroflag=TRUE; |
||
5456 | |||
5457 | } |
||
5458 | |||
5459 | op66(razr); |
||
5460 | |||
5461 | setzeroflag=TRUE; |
||
5462 | |||
5463 | } |
||
5464 | |||
5465 | if(!optimizespeed&&num==2&&((razr==r16&&am32==FALSE)||(razr==r32&&am32))){ |
||
5466 | |||
5467 | op(0x48+reg); |
||
5468 | |||
5469 | setzeroflag=TRUE; |
||
5470 | |||
5471 | } |
||
5472 | |||
5473 | op66(razr); |
||
5474 | |||
5475 | op66(razr); |
||
5476 | |||
5477 | setzeroflag=TRUE; |
||
5478 | |||
5479 | } |
||
5480 | |||
5481 | if((razr==r16&&(unsigned short)num==0xffff)|| |
||
5482 | |||
5483 | if(vop==0x28){ //-= |
||
5484 | |||
5485 | op(0x40+reg); |
||
5486 | |||
5487 | return TRUE; |
||
5488 | |||
5489 | if(vop==0){ //+= |
||
5490 | |||
5491 | op(0x48+reg); |
||
5492 | |||
5493 | return TRUE; |
||
5494 | |||
5495 | if(vop==0x20)return TRUE; //&= |
||
5496 | |||
5497 | if(optimizespeed&&(chip==5||chip==6))return FALSE; |
||
5498 | |||
5499 | op(0xF7); |
||
5500 | |||
5501 | setzeroflag=FALSE; |
||
5502 | |||
5503 | } |
||
5504 | |||
5505 | if(vop==0x20){ //&= |
||
5506 | |||
5507 | if(razr==r16&&(unsigned short)num>=0xFF00&®<4){ |
||
5508 | |||
5509 | else{ |
||
5510 | |||
5511 | op(0xE0+reg); |
||
5512 | |||
5513 | op(num); |
||
5514 | |||
5515 | } |
||
5516 | |||
5517 | op66(r16); |
||
5518 | |||
5519 | else{ |
||
5520 | |||
5521 | op(0xE0+reg); |
||
5522 | |||
5523 | outword(num); |
||
5524 | |||
5525 | } |
||
5526 | |||
5527 | if(!optimizespeed&&(razr==r16&&(unsigned short)num==0xfffe&&am32==FALSE)|| |
||
5528 | |||
5529 | if(vop==0x28){ //-= |
||
5530 | |||
5531 | op(0x40+reg); |
||
5532 | |||
5533 | return TRUE; |
||
5534 | |||
5535 | if(vop==0){ //+= |
||
5536 | |||
5537 | op(0x48+reg); |
||
5538 | |||
5539 | return TRUE; |
||
5540 | |||
5541 | } |
||
5542 | |||
5543 | op66(razr); |
||
5544 | |||
5545 | op(0xC0+vop+reg); |
||
5546 | |||
5547 | setzeroflag=TRUE; |
||
5548 | |||
5549 | } |
||
5550 | |||
5551 | } |
||
5552 | |||
5553 | int dobeg(int beg,int terminater) |
||
5554 | |||
5555 | unsigned char next=1; |
||
5556 | |||
5557 | int rettype=tk_beg,pointr=0;; |
||
5558 | |||
5559 | int numpointr=0; |
||
5560 | |||
5561 | nexttok(); |
||
5562 | |||
5563 | case tk_assign: |
||
5564 | |||
5565 | ofsstr=GetLecsem(terminater); |
||
5566 | |||
5567 | else{ |
||
5568 | |||
5569 | if(RegToReg(beg,itok.number,r8)==NOINREG)goto nn1; |
||
5570 | |||
5571 | break; |
||
5572 | |||
5573 | if(ofsstr){ |
||
5574 | |||
5575 | if((retreg=CheckIDZReg(ofsstr,beg,r8))!=NOINREG){ |
||
5576 | |||
5577 | tok=tk_beg; |
||
5578 | |||
5579 | goto nn1; |
||
5580 | |||
5581 | } |
||
5582 | |||
5583 | convert_type(&sign,&rrettype,&pointr,am32==TRUE?(beg>3?beg-4:beg):BX); |
||
5584 | |||
5585 | nexttok(); |
||
5586 | |||
5587 | } |
||
5588 | |||
5589 | if(tok2==tk_assign){ |
||
5590 | |||
5591 | if(ofsstr){ |
||
5592 | |||
5593 | ofsstr=NULL; |
||
5594 | |||
5595 | if(beg!=hnumber){ |
||
5596 | |||
5597 | op(0xC0+beg+hnumber*8); //mov beg,AL |
||
5598 | |||
5599 | next=0; |
||
5600 | |||
5601 | IDZToReg(ofsstr,beg,r8); |
||
5602 | |||
5603 | } |
||
5604 | |||
5605 | } |
||
5606 | |||
5607 | nn1: |
||
5608 | |||
5609 | if(rrettype==tk_char||rrettype==tk_byte)rettype=doalmath(sign,&ofsstr); |
||
5610 | |||
5611 | else rettype=do_e_axmath(sign,r32,&ofsstr); |
||
5612 | |||
5613 | } |
||
5614 | |||
5615 | if(rrettype==tk_char||rrettype==tk_byte||beg>BL){ |
||
5616 | |||
5617 | if(itok.type!=tp_stopper&&tok!=tk_eof){ |
||
5618 | |||
5619 | rettype=tk_beg; |
||
5620 | |||
5621 | } |
||
5622 | |||
5623 | if(rrettype==tk_int||rrettype==tk_word)next=r16; |
||
5624 | |||
5625 | rettype=getintoreg(beg,next,sign,&ofsstr); |
||
5626 | |||
5627 | next=0; |
||
5628 | |||
5629 | if(ofsstr){ |
||
5630 | |||
5631 | free(ofsstr); |
||
5632 | |||
5633 | break; |
||
5634 | |||
5635 | ClearReg(beg>3?beg%4:beg); |
||
5636 | |||
5637 | case tk_minusminus: op(0xFE); op(0xC8+beg); |
||
5638 | |||
5639 | break; |
||
5640 | |||
5641 | getoperand(beg==BL||beg==BH?SI:BX); |
||
5642 | |||
5643 | case tk_charvar: |
||
5644 | |||
5645 | CheckAllMassiv(bufrm,1,&strinf); |
||
5646 | |||
5647 | op(0x86); |
||
5648 | |||
5649 | outaddress(&itok); |
||
5650 | |||
5651 | ClearReg(beg>3?beg-4:beg); |
||
5652 | |||
5653 | case tk_beg: |
||
5654 | |||
5655 | if(RegSwapReg(beg,itok.number,r8)==NOINREG){ |
||
5656 | |||
5657 | op(0xC0+(unsigned int)itok.number+beg*8); |
||
5658 | |||
5659 | else waralreadinitreg(begs[beg],begs[itok.number]); |
||
5660 | |||
5661 | break; |
||
5662 | |||
5663 | } |
||
5664 | |||
5665 | case tk_xorequals: vop+=0x08; |
||
5666 | |||
5667 | case tk_andequals: vop+=0x18; |
||
5668 | |||
5669 | case tk_plusequals: |
||
5670 | |||
5671 | if(CheckAddOnly()){ |
||
5672 | |||
5673 | cha2=' '; |
||
5674 | |||
5675 | else tok=tk_minus; |
||
5676 | |||
5677 | else dobegmath(beg); |
||
5678 | |||
5679 | break; |
||
5680 | |||
5681 | getoperand(beg==BL||beg==BH?SI:BX); |
||
5682 | |||
5683 | if(beg==AL){ |
||
5684 | |||
5685 | dobegmath(CL); |
||
5686 | |||
5687 | } |
||
5688 | |||
5689 | doalmath(0,&ofsstr); |
||
5690 | |||
5691 | } |
||
5692 | |||
5693 | op(0x00+vop); |
||
5694 | |||
5695 | next=0; |
||
5696 | |||
5697 | } |
||
5698 | |||
5699 | case tk_number: |
||
5700 | |||
5701 | next=0; |
||
5702 | |||
5703 | if(i==255&&vop==0x20)break; |
||
5704 | |||
5705 | else{ |
||
5706 | |||
5707 | op(0xC0+vop+beg); |
||
5708 | |||
5709 | op(i); |
||
5710 | |||
5711 | case tk_qwordvar: |
||
5712 | |||
5713 | case tk_longvar: |
||
5714 | |||
5715 | i+=2; |
||
5716 | |||
5717 | case tk_intvar: |
||
5718 | |||
5719 | case tk_charvar: |
||
5720 | |||
5721 | i++; |
||
5722 | |||
5723 | outseg(&itok,2); |
||
5724 | |||
5725 | op(beg*8+itok.rm); |
||
5726 | |||
5727 | break; |
||
5728 | |||
5729 | op(0x00+vop); |
||
5730 | |||
5731 | break; |
||
5732 | |||
5733 | case tk_apiproc: |
||
5734 | |||
5735 | case tk_declare: |
||
5736 | |||
5737 | case tk_id: |
||
5738 | |||
5739 | i=beg<4?beg:beg-4; |
||
5740 | |||
5741 | addESP+=2; |
||
5742 | |||
5743 | procdo(tk_byte); |
||
5744 | |||
5745 | nexttok(); |
||
5746 | |||
5747 | next=0; |
||
5748 | |||
5749 | addESP-=2; |
||
5750 | |||
5751 | op(0x58+(i!=AX?i:CX)); |
||
5752 | |||
5753 | op(0x00+vop); |
||
5754 | |||
5755 | } |
||
5756 | |||
5757 | if(vop>0x20){ |
||
5758 | |||
5759 | op(0xC0+CL+beg); //xchg al,cl |
||
5760 | |||
5761 | op(0x00+vop); |
||
5762 | |||
5763 | } |
||
5764 | |||
5765 | case tk_reg: |
||
5766 | |||
5767 | op(0x00+vop); |
||
5768 | |||
5769 | } |
||
5770 | |||
5771 | break; |
||
5772 | |||
5773 | default: valueexpected(); break; |
||
5774 | |||
5775 | break; |
||
5776 | |||
5777 | case tk_llequals: |
||
5778 | |||
5779 | ClearReg(beg>3?beg%4:beg); |
||
5780 | |||
5781 | if((unsigned int)itok.number==1){ |
||
5782 | |||
5783 | } /* SHL beg,1 */ |
||
5784 | |||
5785 | if(chip<2)goto shiftbeg; |
||
5786 | |||
5787 | op(0xc0); |
||
5788 | |||
5789 | op((unsigned int)itok.number); |
||
5790 | |||
5791 | } |
||
5792 | |||
5793 | else{ |
||
5794 | |||
5795 | if(beg!=CL){ |
||
5796 | |||
5797 | op(0xD2); op(0xE0+vop+beg); /* SHL beg,CL */ |
||
5798 | |||
5799 | else{ |
||
5800 | |||
5801 | getintobeg(CL,&ofsstr); |
||
5802 | |||
5803 | next=0; |
||
5804 | |||
5805 | op(0xD2); op(0xE0+vop+beg); /* SHL beg,CL */ |
||
5806 | |||
5807 | } |
||
5808 | |||
5809 | } |
||
5810 | |||
5811 | default: operatorexpected(); break; |
||
5812 | |||
5813 | if(next)nexttok(); |
||
5814 | |||
5815 | return rettype; |
||
5816 | |||
5817 | |||
5818 | |||
5819 | { |
||
5820 | |||
5821 | int numpointr=0; |
||
5822 | |||
5823 | if(seg==CS)preerror("CS not used for destention"); |
||
5824 | |||
5825 | if(seg==SS)RestoreStack(); |
||
5826 | |||
5827 | KillVar(segs[seg]); |
||
5828 | |||
5829 | nexttok(); |
||
5830 | |||
5831 | nexttok(); |
||
5832 | |||
5833 | } |
||
5834 | |||
5835 | if(tok2==tk_assign){ |
||
5836 | |||
5837 | if(ofsstr){ |
||
5838 | |||
5839 | ofsstr=NULL; |
||
5840 | |||
5841 | goto getfromreg; |
||
5842 | |||
5843 | if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr); |
||
5844 | |||
5845 | switch(tok){ |
||
5846 | |||
5847 | getfromreg: |
||
5848 | |||
5849 | op(0xC0+seg*8+(unsigned int)itok.number); /* MOV seg,reg */ |
||
5850 | |||
5851 | case tk_intvar: |
||
5852 | |||
5853 | case tk_longvar: |
||
5854 | |||
5855 | case tk_qwordvar: |
||
5856 | |||
5857 | op66(r16); |
||
5858 | |||
5859 | op(0x8E); |
||
5860 | |||
5861 | outaddress(&itok); /* MOV seg,[wordvar] */ |
||
5862 | |||
5863 | case tk_seg: |
||
5864 | |||
5865 | PushSeg((unsigned int)itok.number); |
||
5866 | |||
5867 | break; |
||
5868 | |||
5869 | goto segax; |
||
5870 | |||
5871 | if(regoverstack&&chip>1){ |
||
5872 | |||
5873 | if(short_ok(itok.number)&&(itok.flag&f_reloc)==0){ |
||
5874 | |||
5875 | op(itok.number); |
||
5876 | |||
5877 | else{ |
||
5878 | |||
5879 | if((itok.flag&f_reloc)!=0)AddReloc(); |
||
5880 | |||
5881 | else outword(itok.number); |
||
5882 | |||
5883 | PopSeg(seg); |
||
5884 | |||
5885 | break; |
||
5886 | |||
5887 | goto segax; |
||
5888 | |||
5889 | } |
||
5890 | |||
5891 | else{ |
||
5892 | |||
5893 | do_e_axmath(0,r16,&ofsstr); |
||
5894 | |||
5895 | op(0xC0+seg*8); |
||
5896 | |||
5897 | } |
||
5898 | |||
5899 | else if(tok==tk_swap){ |
||
5900 | |||
5901 | switch(tok){ |
||
5902 | |||
5903 | case tk_wordvar: |
||
5904 | |||
5905 | op66(r16); |
||
5906 | |||
5907 | op(0xC0+seg*8); /* MOV AX,SEG */ |
||
5908 | |||
5909 | op66(r16); |
||
5910 | |||
5911 | op(0x87); |
||
5912 | |||
5913 | outaddress(&itok); /* XCHG AX,[word] */ |
||
5914 | |||
5915 | op(0x8E); |
||
5916 | |||
5917 | break; |
||
5918 | |||
5919 | KillVar(segs[itok.number]); |
||
5920 | |||
5921 | PushSeg(itok.number); |
||
5922 | |||
5923 | PopSeg(itok.number); |
||
5924 | |||
5925 | default: preerror("Only int, word variables valid for segment register ><"); |
||
5926 | |||
5927 | } |
||
5928 | |||
5929 | else segoperror(); |
||
5930 | |||
5931 | else seminext(); |
||
5932 | |||
5933 | |||
5934 | |||
5935 | { |
||
5936 | |||
5937 | case DS: op(0x1E); break; |
||
5938 | |||
5939 | case SS: op(0x16); break; |
||
5940 | |||
5941 | case FS: outword(0xA00F); if(cpu<3)cpu=3; break; |
||
5942 | |||
5943 | } |
||
5944 | |||
5945 | |||
5946 | |||
5947 | { |
||
5948 | |||
5949 | case DS: op(0x1F); break; |
||
5950 | |||
5951 | case ES: op(0x07); break; |
||
5952 | |||
5953 | case GS: outword(0xA90F); if(cpu<3)cpu=3; break; |
||
5954 | |||
5955 | } |
||
5956 | |||
5957 | // =============== doregmath_32(), dobegmath() =============== |
||
5958 | |||
5959 | void doregmath_32(int reg,int razr,int sign,char **ofsstr,int fdiv) // math done is on all regs except AX |
||
5960 | |||
5961 | { |
||
5962 | |||
5963 | while(itok.type!=tp_stopper&&tok!=tk_eof){ |
||
5964 | |||
5965 | NegReg(razr,reg); |
||
5966 | |||
5967 | } |
||
5968 | |||
5969 | optnum=FALSE; |
||
5970 | |||
5971 | CheckConstVar3(&tok2,&itok2,razr); |
||
5972 | |||
5973 | #endif |
||
5974 | |||
5975 | if(razr==r32){ |
||
5976 | |||
5977 | } |
||
5978 | |||
5979 | if(itok.type==tp_stopper||tok==tk_eof)break; |
||
5980 | |||
5981 | if(tok2==tk_number)optnum=OptimNum(); |
||
5982 | |||
5983 | case tk_xor: vop+=0x08; |
||
5984 | |||
5985 | case tk_and: vop+=0x18; |
||
5986 | |||
5987 | case tk_plus: |
||
5988 | |||
5989 | else tok=tk_number; |
||
5990 | |||
5991 | case tk_number: |
||
5992 | |||
5993 | case tk_postnumber: |
||
5994 | |||
5995 | op66(razr); |
||
5996 | |||
5997 | op(0xC0+vop+reg); |
||
5998 | |||
5999 | else if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
6000 | |||
6001 | razr==r16?outword((unsigned int)itok.number):outdword(itok.number); |
||
6002 | |||
6003 | case tk_apioffset: |
||
6004 | |||
6005 | op(0x81); |
||
6006 | |||
6007 | AddApiToPost(itok.number); |
||
6008 | |||
6009 | case tk_doublevar: |
||
6010 | |||
6011 | case tk_floatvar: |
||
6012 | |||
6013 | itok.number=EAX; |
||
6014 | |||
6015 | goto defreg32; |
||
6016 | |||
6017 | int vops,reg2s; |
||
6018 | |||
6019 | if(i<=64)vops=r64; |
||
6020 | |||
6021 | if(i<=16)vops=r16; |
||
6022 | |||
6023 | reg2s=CX; |
||
6024 | |||
6025 | bits2reg(reg2s,vops); |
||
6026 | |||
6027 | warningreg(regs[vops/2-1][reg2s]); |
||
6028 | |||
6029 | goto defreg32; |
||
6030 | |||
6031 | if(razr==r32){ |
||
6032 | |||
6033 | outword(0xB70F); |
||
6034 | |||
6035 | op(0xC0+reg); |
||
6036 | |||
6037 | } |
||
6038 | |||
6039 | warningreg(regs[razr/2-1][itok.number]); |
||
6040 | |||
6041 | case tk_reg32: |
||
6042 | |||
6043 | op66(razr); |
||
6044 | |||
6045 | op(0xC0+reg+(unsigned int)itok.number*8); |
||
6046 | |||
6047 | case tk_qwordvar: |
||
6048 | |||
6049 | case tk_dwordvar: |
||
6050 | |||
6051 | goto wordvar; |
||
6052 | |||
6053 | case tk_wordvar: |
||
6054 | |||
6055 | i=2; |
||
6056 | |||
6057 | CheckAllMassiv(bufrm,i,&strinf); |
||
6058 | |||
6059 | outseg(&itok,2); |
||
6060 | |||
6061 | op(reg*8+itok.rm); |
||
6062 | |||
6063 | break; |
||
6064 | |||
6065 | case tk_beg: |
||
6066 | |||
6067 | case tk_seg: |
||
6068 | |||
6069 | addchar: |
||
6070 | |||
6071 | ITOK wtok; |
||
6072 | |||
6073 | wstr=strinf; |
||
6074 | |||
6075 | wbuf=bufrm; |
||
6076 | |||
6077 | wtok=itok; |
||
6078 | |||
6079 | goto addax; |
||
6080 | |||
6081 | case tk_id: |
||
6082 | |||
6083 | case tk_apiproc: |
||
6084 | |||
6085 | case tk_declare: |
||
6086 | |||
6087 | if(!(comfile==file_w32&&(reg==EBX||reg==EDI||reg==ESI))){ |
||
6088 | |||
6089 | op(0x50+reg); //push AX |
||
6090 | |||
6091 | addESP+=razr==r16?2:4; |
||
6092 | |||
6093 | addstack=FALSE; |
||
6094 | |||
6095 | addstack=oaddstack; |
||
6096 | |||
6097 | if(!(comfile==file_w32&&(reg==EBX||reg==EDI||reg==ESI))){ |
||
6098 | |||
6099 | op(0x58+reg); |
||
6100 | |||
6101 | addax: |
||
6102 | |||
6103 | op(0x01+vop); |
||
6104 | |||
6105 | warningreg(regs[razr/2-1][0]); |
||
6106 | |||
6107 | default: valueexpected(); break; |
||
6108 | |||
6109 | break; |
||
6110 | |||
6111 | case tk_andminus: vop+=0x18; |
||
6112 | |||
6113 | getoperand(reg==BX?SI:BX); |
||
6114 | |||
6115 | case tk_number: |
||
6116 | |||
6117 | op66(razr); |
||
6118 | |||
6119 | op(0xC0+vop+reg); |
||
6120 | |||
6121 | razr==r16?outword((unsigned int)itok.number):outdword(itok.number); |
||
6122 | |||
6123 | case tk_ID: |
||
6124 | |||
6125 | case tk_proc: |
||
6126 | |||
6127 | case tk_undefproc: |
||
6128 | |||
6129 | |||
6130 | |||
6131 | if(*ofsstr!=NULL){ |
||
6132 | |||
6133 | *ofsstr=NULL; |
||
6134 | |||
6135 | goto defxormin; |
||
6136 | |||
6137 | if(reg==ECX){ |
||
6138 | |||
6139 | SINFO wstr; |
||
6140 | |||
6141 | strinf.bufstr=NULL; |
||
6142 | |||
6143 | char *wbuf; |
||
6144 | |||
6145 | bufrm=NULL; |
||
6146 | |||
6147 | getinto_e_ax(sign,tok,&wtok,wbuf,&wstr,razr); |
||
6148 | |||
6149 | else{ |
||
6150 | |||
6151 | getintoreg_32(CX,razr,sign,ofsstr,FALSE); |
||
6152 | |||
6153 | defxormin: |
||
6154 | |||
6155 | op66(razr); |
||
6156 | |||
6157 | op(0xC0+i*8+reg); |
||
6158 | |||
6159 | if(i==ECX)continue; |
||
6160 | |||
6161 | } |
||
6162 | |||
6163 | case tk_rrminus: |
||
6164 | |||
6165 | regmathoperror(); |
||
6166 | |||
6167 | } |
||
6168 | |||
6169 | getintobeg(CL,ofsstr); |
||
6170 | |||
6171 | op(0xD3); |
||
6172 | |||
6173 | warningreg(begs[1]); |
||
6174 | |||
6175 | case tk_rr: |
||
6176 | |||
6177 | if(RshiftReg(razr,reg,sign)==FALSE)regmathoperror(); |
||
6178 | |||
6179 | break; |
||
6180 | |||
6181 | if(reg==ECX){ |
||
6182 | |||
6183 | break; |
||
6184 | |||
6185 | tok=tk_minus; |
||
6186 | |||
6187 | case tk_ll: |
||
6188 | |||
6189 | if(tok==tk_number){ |
||
6190 | |||
6191 | regmathoperror(); |
||
6192 | |||
6193 | } |
||
6194 | |||
6195 | } |
||
6196 | |||
6197 | op66(razr); |
||
6198 | |||
6199 | |||
6200 | |||
6201 | else if(reg!=ECX){ |
||
6202 | |||
6203 | getintobeg(CL,ofsstr); |
||
6204 | |||
6205 | op(0xD3); |
||
6206 | |||
6207 | warningreg(begs[1]); |
||
6208 | |||
6209 | } |
||
6210 | |||
6211 | break; |
||
6212 | |||
6213 | case tk_mult: |
||
6214 | |||
6215 | else tok=tk_number; |
||
6216 | |||
6217 | itok.number=-itok.number; |
||
6218 | |||
6219 | } |
||
6220 | |||
6221 | break; |
||
6222 | |||
6223 | case tk_mod: |
||
6224 | |||
6225 | goto divcalc; |
||
6226 | |||
6227 | case tk_div: |
||
6228 | |||
6229 | if(optnum==FALSE)getoperand(reg==BX?SI:BX); |
||
6230 | |||
6231 | if(negflag&&tok==tk_number){ |
||
6232 | |||
6233 | negflag=FALSE; |
||
6234 | |||
6235 | if(tok==tk_number&&(i=caselong(itok.number))!=NUMNUM){ |
||
6236 | |||
6237 | itok.number--; |
||
6238 | |||
6239 | ZeroReg(reg,razr); |
||
6240 | |||
6241 | else if(short_ok(itok.number,razr/2-1)){ |
||
6242 | |||
6243 | op(0x83); |
||
6244 | |||
6245 | op(itok.number); |
||
6246 | |||
6247 | else{ |
||
6248 | |||
6249 | op(0x81); |
||
6250 | |||
6251 | razr==r16?outword((unsigned int)itok.number):outdword(itok.number); |
||
6252 | |||
6253 | } |
||
6254 | |||
6255 | if(i!=0){ |
||
6256 | |||
6257 | if(reg==CX)regmathoperror(); |
||
6258 | |||
6259 | op(0xD3); |
||
6260 | |||
6261 | warningreg(begs[1]); |
||
6262 | |||
6263 | else{ |
||
6264 | |||
6265 | op(0xC1); |
||
6266 | |||
6267 | op(i); |
||
6268 | |||
6269 | } |
||
6270 | |||
6271 | break; |
||
6272 | |||
6273 | if(fdiv!=1){ |
||
6274 | |||
6275 | op(0x90+reg); //xchg AX,reg |
||
6276 | |||
6277 | DivMod(vop,sign,razr,0); |
||
6278 | |||
6279 | if(vop==1){ |
||
6280 | |||
6281 | if(optimizespeed)outword(0xC28B); //mov ax,dx |
||
6282 | |||
6283 | } |
||
6284 | |||
6285 | } |
||
6286 | |||
6287 | if(reg!=EDX){ |
||
6288 | |||
6289 | op(0x89); |
||
6290 | |||
6291 | } |
||
6292 | |||
6293 | continue; |
||
6294 | |||
6295 | op66(razr); |
||
6296 | |||
6297 | op(0x89); |
||
6298 | |||
6299 | } |
||
6300 | |||
6301 | warningreg(regs[razr/2-1][EAX]); |
||
6302 | |||
6303 | default: operatorexpected(); break; |
||
6304 | |||
6305 | calcnumber=FALSE; |
||
6306 | |||
6307 | nexttok(); |
||
6308 | |||
6309 | calcnumber=FALSE; |
||
6310 | |||
6311 | if(razr==r32&&cpu<3)cpu=3; |
||
6312 | |||
6313 | |||
6314 | |||
6315 | // all other registers preserved |
||
6316 | |||
6317 | int vop,i,optnum=FALSE,negflag=FALSE; |
||
6318 | |||
6319 | vop=0; |
||
6320 | |||
6321 | #ifdef OPTVARCONST |
||
6322 | |||
6323 | if(CheckConstVar(&itok2)){ |
||
6324 | |||
6325 | calcnumber=TRUE; |
||
6326 | |||
6327 | } |
||
6328 | |||
6329 | if(tok2==tk_number)optnum=OptimNum(); |
||
6330 | |||
6331 | switch(tok){ |
||
6332 | |||
6333 | case tk_minus: vop+=0x08; |
||
6334 | |||
6335 | case tk_or: vop+=0x08; |
||
6336 | |||
6337 | if(optnum==FALSE)getoperand(beg==BL||beg==BH?SI:BX); |
||
6338 | |||
6339 | tok=tk_number; |
||
6340 | |||
6341 | } |
||
6342 | |||
6343 | case tk_number: |
||
6344 | |||
6345 | else if(itok.number==1){ |
||
6346 | |||
6347 | op(0xFE); |
||
6348 | |||
6349 | break; |
||
6350 | |||
6351 | if(oldtok==tk_minus){ |
||
6352 | |||
6353 | op(0xC8+beg); |
||
6354 | |||
6355 | } |
||
6356 | |||
6357 | else if((unsigned char)itok.number==0xff){ |
||
6358 | |||
6359 | op(0xFE); |
||
6360 | |||
6361 | break; |
||
6362 | |||
6363 | if(oldtok==tk_plus){ |
||
6364 | |||
6365 | op(0xC8+beg); |
||
6366 | |||
6367 | } |
||
6368 | |||
6369 | op(0x80); |
||
6370 | |||
6371 | op((unsigned int)itok.number); |
||
6372 | |||
6373 | case tk_bits: |
||
6374 | |||
6375 | i=itok.bit.siz+itok.bit.ofs; |
||
6376 | |||
6377 | if(i<=32)vops=r32; |
||
6378 | |||
6379 | if(i<=8)vops=r8; |
||
6380 | |||
6381 | if(beg==CL)reg2s=BL; |
||
6382 | |||
6383 | if(vops==r64)vops=r32; |
||
6384 | |||
6385 | itok.number=reg2s; |
||
6386 | |||
6387 | op(0x00+vop); |
||
6388 | |||
6389 | break; |
||
6390 | |||
6391 | i=4; |
||
6392 | |||
6393 | case tk_dwordvar: |
||
6394 | |||
6395 | case tk_intvar: |
||
6396 | |||
6397 | i++; |
||
6398 | |||
6399 | case tk_charvar: |
||
6400 | |||
6401 | CheckAllMassiv(bufrm,i,&strinf); |
||
6402 | |||
6403 | op(0x02+vop); |
||
6404 | |||
6405 | outaddress(&itok); |
||
6406 | |||
6407 | case tk_postnumber: |
||
6408 | |||
6409 | case tk_rmnumber: begworderror(); break; |
||
6410 | |||
6411 | case tk_id: |
||
6412 | |||
6413 | case tk_apiproc: |
||
6414 | |||
6415 | case tk_declare: |
||
6416 | |||
6417 | if(beg!=AL){ |
||
6418 | |||
6419 | op(0xc0+beg); |
||
6420 | |||
6421 | break; |
||
6422 | |||
6423 | } |
||
6424 | |||
6425 | case tk_xorminus: vop+=0x10; |
||
6426 | |||
6427 | case tk_orminus: vop+=0x08; |
||
6428 | |||
6429 | if(tok==tk_number){ |
||
6430 | |||
6431 | op(0x80); |
||
6432 | |||
6433 | op((unsigned int)itok.number); |
||
6434 | |||
6435 | else negregerror(); |
||
6436 | |||
6437 | case tk_rr: |
||
6438 | |||
6439 | case tk_ll: |
||
6440 | |||
6441 | if(tok==tk_number){ |
||
6442 | |||
6443 | if(vop==0){ |
||
6444 | |||
6445 | op(0xC0+9*beg); // ADD reg,reg |
||
6446 | |||
6447 | else{ |
||
6448 | |||
6449 | } |
||
6450 | |||
6451 | else if((unsigned int)itok.number!=0){ |
||
6452 | |||
6453 | else{ |
||
6454 | |||
6455 | op(0xe0+beg+vop); // SHL reg,imm8 |
||
6456 | |||
6457 | if(cpu<2)cpu=2; |
||
6458 | |||
6459 | } |
||
6460 | |||
6461 | else if(tok==tk_beg&&itok.number==CL&&beg!=CL){ |
||
6462 | |||
6463 | op(0xE0+beg+vop); // SHL xXX,CL |
||
6464 | |||
6465 | else begmathoperror(); |
||
6466 | |||
6467 | case tk_multminus: negflag=TRUE; |
||
6468 | |||
6469 | if(optnum==FALSE)getoperand(beg==BL||beg==BH?SI:BX); |
||
6470 | |||
6471 | tok=tk_number; |
||
6472 | |||
6473 | } |
||
6474 | |||
6475 | itok.number=-itok.number; |
||
6476 | |||
6477 | } |
||
6478 | |||
6479 | case tk_number: |
||
6480 | |||
6481 | switch((unsigned int)itok.number){ |
||
6482 | |||
6483 | outword(0x00B0+beg); |
||
6484 | |||
6485 | case 2: |
||
6486 | |||
6487 | op(0xC0+9*beg); // beg * 2 = ADD beg,beg |
||
6488 | |||
6489 | default: |
||
6490 | |||
6491 | if(vop!=NUMNUM){ |
||
6492 | |||
6493 | else{ |
||
6494 | |||
6495 | op(0xe0+beg); //SHL beg,num |
||
6496 | |||
6497 | if(cpu<1)cpu=1; |
||
6498 | |||
6499 | } |
||
6500 | |||
6501 | } |
||
6502 | |||
6503 | default: begmathoperror(); break; |
||
6504 | |||
6505 | break; |
||
6506 | |||
6507 | case tk_modminus: |
||
6508 | |||
6509 | case tk_mod: |
||
6510 | |||
6511 | case tk_llminus: |
||
6512 | |||
6513 | default: operatorexpected(); break; |
||
6514 | |||
6515 | #ifdef OPTVARCONST |
||
6516 | |||
6517 | #endif |
||
6518 | |||
6519 | ClearReg(beg%4); |
||
6520 | |||
6521 | } |
||
6522 | |||
6523 | // ============= getintoreg_32(), getintobeg() ============ |
||
6524 | |||
6525 | int getintoreg_32(int reg,int razr,int sign,char **ofsstr,int useloop) // get into word reg (except AX) with enum |
||
6526 | |||
6527 | int negflag=0,next=1,i=0; |
||
6528 | |||
6529 | unsigned long holdnumber=0; |
||
6530 | |||
6531 | int rettype=tk_reg; |
||
6532 | |||
6533 | // printf("line %d tok=%d %s\n",linenumber,tok,itok.name); |
||
6534 | |||
6535 | if(reg==idxregs[1]||reg==idxregs[2]){ |
||
6536 | |||
6537 | if(reg==idxregs[1])reg2=idxregs[0]; |
||
6538 | |||
6539 | } |
||
6540 | |||
6541 | reg1=reg; |
||
6542 | |||
6543 | } |
||
6544 | |||
6545 | if(CheckMinusNum()==FALSE){ |
||
6546 | |||
6547 | getoperand(am32==FALSE?BX:reg); |
||
6548 | |||
6549 | } |
||
6550 | |||
6551 | |||
6552 | |||
6553 | if(razr==r32){ |
||
6554 | |||
6555 | if(Reg32ToLea(reg)){ |
||
6556 | |||
6557 | } |
||
6558 | |||
6559 | else |
||
6560 | |||
6561 | return tk_reg; |
||
6562 | |||
6563 | } |
||
6564 | |||
6565 | |||
6566 | |||
6567 | CheckConstVar3(&tok,&itok,razr); |
||
6568 | |||
6569 | #endif |
||
6570 | |||
6571 | // printf("reg=%d tok=%d\n",reg,tok); |
||
6572 | |||
6573 | case tk_number: |
||
6574 | |||
6575 | else{ |
||
6576 | |||
6577 | if(loop==0)oflag=postnumflag; |
||
6578 | |||
6579 | loop++; |
||
6580 | |||
6581 | nexttok(); |
||
6582 | |||
6583 | goto loopswitch1; |
||
6584 | |||
6585 | if(tok==tk_plus&&tok2==tk_postnumber){ |
||
6586 | |||
6587 | // getoperand(am32==TRUE?EAX:BX); |
||
6588 | |||
6589 | } |
||
6590 | |||
6591 | next=0; |
||
6592 | |||
6593 | break; |
||
6594 | |||
6595 | case tk_undefofs: |
||
6596 | |||
6597 | op66(razr); |
||
6598 | |||
6599 | swap=1; |
||
6600 | |||
6601 | if(tok==tk_undefofs){ |
||
6602 | |||
6603 | // AddUndefOff(0,itok.name); |
||
6604 | |||
6605 | } |
||
6606 | |||
6607 | if(useloop==FALSE)holdnumber=itok.number; |
||
6608 | |||
6609 | tok=tk_number; |
||
6610 | |||
6611 | if(otok!=tk_postnumber){ |
||
6612 | |||
6613 | else oflag^=postnumflag; |
||
6614 | |||
6615 | } |
||
6616 | |||
6617 | nexttok(); |
||
6618 | |||
6619 | } |
||
6620 | |||
6621 | next=0; |
||
6622 | |||
6623 | if(useloop&&(oflag&f_reloc))AddReloc(); |
||
6624 | |||
6625 | else outdword(holdnumber); |
||
6626 | |||
6627 | break; |
||
6628 | |||
6629 | op66(razr); |
||
6630 | |||
6631 | AddApiToPost(itok.number); |
||
6632 | |||
6633 | break; |
||
6634 | |||
6635 | CheckAllMassiv(bufrm,itok.size,&strinf,&itok,reg1,reg2); |
||
6636 | |||
6637 | (reg==SI||reg==DI||reg==BX)))break; |
||
6638 | |||
6639 | op67(itok.sib==CODE16?r16:r32); |
||
6640 | |||
6641 | op(0x8D); // LEA reg,[rm] |
||
6642 | |||
6643 | if(itok.post!=0&&itok.post!=UNDEF_OFSET){ |
||
6644 | |||
6645 | unsigned int ooutptr=outptr; |
||
6646 | |||
6647 | setwordpost(&itok); |
||
6648 | |||
6649 | } |
||
6650 | |||
6651 | } |
||
6652 | |||
6653 | else{ |
||
6654 | |||
6655 | oitok=itok; |
||
6656 | |||
6657 | itok.rm=tk_dword; |
||
6658 | |||
6659 | outaddress(&oitok); |
||
6660 | |||
6661 | } |
||
6662 | |||
6663 | break; |
||
6664 | |||
6665 | i=4; |
||
6666 | |||
6667 | case tk_dwordvar: |
||
6668 | |||
6669 | dwordvar: |
||
6670 | |||
6671 | op66(razr); |
||
6672 | |||
6673 | op(0x8B); |
||
6674 | |||
6675 | outaddress(&itok); |
||
6676 | |||
6677 | break; |
||
6678 | |||
6679 | case tk_wordvar: |
||
6680 | |||
6681 | if(razr==r16)goto dwordvar; |
||
6682 | |||
6683 | if(tok==tk_wordvar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ |
||
6684 | |||
6685 | op66(r16); |
||
6686 | |||
6687 | op(0x8B); |
||
6688 | |||
6689 | else{ |
||
6690 | |||
6691 | outseg(&itok,3); //movxx reg,var |
||
6692 | |||
6693 | } |
||
6694 | |||
6695 | outaddress(&itok); |
||
6696 | |||
6697 | break; |
||
6698 | |||
6699 | i=4; |
||
6700 | |||
6701 | Float2reg32(reg,i,reg1,reg2); |
||
6702 | |||
6703 | break; |
||
6704 | |||
6705 | case tk_charvar: |
||
6706 | |||
6707 | CheckAllMassiv(bufrm,1,&strinf,&itok,reg1,reg2); |
||
6708 | |||
6709 | ZeroReg(reg,razr); |
||
6710 | |||
6711 | op(0x8A); |
||
6712 | |||
6713 | else{ |
||
6714 | |||
6715 | outseg(&itok,3); |
||
6716 | |||
6717 | if(tok==tk_bytevar)op(0xb6); |
||
6718 | |||
6719 | } |
||
6720 | |||
6721 | outaddress(&itok); |
||
6722 | |||
6723 | break; |
||
6724 | |||
6725 | if(reg<=BX){ |
||
6726 | |||
6727 | outseg(&itok,1); |
||
6728 | |||
6729 | outword((unsigned int)itok.number); |
||
6730 | |||
6731 | else{ |
||
6732 | |||
6733 | outseg(&itok,2); |
||
6734 | |||
6735 | op(reg*8+itok.rm); // MOV regL,[byte] |
||
6736 | |||
6737 | } |
||
6738 | |||
6739 | op(0x30); op(0xC0+(reg+4)*9); // XOR regH,regH |
||
6740 | |||
6741 | else regbyteerror(); |
||
6742 | |||
6743 | case tk_reg: |
||
6744 | |||
6745 | if(tok2==tk_openbracket){ //вызов процедуры по адресу в регистре |
||
6746 | |||
6747 | nexttok(); |
||
6748 | |||
6749 | if(comfile==file_w32)swapparam(); |
||
6750 | |||
6751 | op66(r16); |
||
6752 | |||
6753 | op(0xD0+reg1); /* CALL reg with stack params */ |
||
6754 | |||
6755 | clearregstat(); |
||
6756 | |||
6757 | FreeGlobalConst(); |
||
6758 | |||
6759 | } |
||
6760 | |||
6761 | ZeroReg(reg,r32); |
||
6762 | |||
6763 | op(0xC0+reg+(unsigned int)itok.number*8); |
||
6764 | |||
6765 | else{ |
||
6766 | |||
6767 | outword(0xB70F); |
||
6768 | |||
6769 | } |
||
6770 | |||
6771 | break; |
||
6772 | |||
6773 | |||
6774 | |||
6775 | reg1=itok.number; |
||
6776 | |||
6777 | nexttok(); |
||
6778 | |||
6779 | if(comfile==file_w32)swapparam(); |
||
6780 | |||
6781 | op66(reg2); |
||
6782 | |||
6783 | op(0xD0+reg1); /* CALL reg with stack params */ |
||
6784 | |||
6785 | clearregstat(); |
||
6786 | |||
6787 | FreeGlobalConst(); |
||
6788 | |||
6789 | } |
||
6790 | |||
6791 | op66(razr); |
||
6792 | |||
6793 | op(0xC0+reg+(unsigned int)itok.number*8); |
||
6794 | |||
6795 | } |
||
6796 | |||
6797 | |||
6798 | |||
6799 | i=itok.bit.siz+itok.bit.ofs; |
||
6800 | |||
6801 | if(i<=32)vops=r32; |
||
6802 | |||
6803 | bits2reg(reg,(razr |
||
6804 | |||
6805 | case tk_seg: |
||
6806 | |||
6807 | op(0x8C); |
||
6808 | |||
6809 | ClearReg(reg); |
||
6810 | |||
6811 | case tk_beg: |
||
6812 | |||
6813 | if(optimizespeed&&chip>3&&chip<7&®<4&®!=(int)(itok.number%4)){ |
||
6814 | |||
6815 | op(0x88); |
||
6816 | |||
6817 | } |
||
6818 | |||
6819 | op66(razr); |
||
6820 | |||
6821 | |||
6822 | |||
6823 | } |
||
6824 | |||
6825 | else{ |
||
6826 | |||
6827 | op(0x30); op(0xC0+(reg+4)*9); // XOR regH,regH |
||
6828 | |||
6829 | ClearReg(reg); |
||
6830 | |||
6831 | case tk_at: |
||
6832 | |||
6833 | i++; |
||
6834 | |||
6835 | case tk_id: |
||
6836 | |||
6837 | case tk_apiproc: |
||
6838 | |||
6839 | case tk_declare: |
||
6840 | |||
6841 | if((!i)||macros(razr==r16?tk_word:tk_dword)==0)procdo(razr==r16?tk_word:tk_dword); |
||
6842 | |||
6843 | tok=(razr==r16?tk_reg:tk_reg32); |
||
6844 | |||
6845 | free(*ofsstr); |
||
6846 | |||
6847 | } |
||
6848 | |||
6849 | goto loopswitch; |
||
6850 | |||
6851 | case tk_string: |
||
6852 | |||
6853 | op(0xB8+reg); |
||
6854 | |||
6855 | if(am32)dwordvalexpected(); |
||
6856 | |||
6857 | } |
||
6858 | |||
6859 | ClearReg(reg); |
||
6860 | |||
6861 | default: valueexpected(); break; |
||
6862 | |||
6863 | #ifdef OPTVARCONST |
||
6864 | |||
6865 | #endif |
||
6866 | |||
6867 | if(swap){ |
||
6868 | |||
6869 | RegMulNum(reg,holdnumber,razr,0,&negflag,oflag); |
||
6870 | |||
6871 | } |
||
6872 | |||
6873 | // printf("tok=%d num=%d tok2=%d\n",tok,itok.number,tok2); |
||
6874 | |||
6875 | } |
||
6876 | |||
6877 | int getintobeg(int beg,char **ofsstr) // get into beg (CL,DL,BL not others) with enum |
||
6878 | |||
6879 | int negflag=0,i=0; |
||
6880 | |||
6881 | if(tok==tk_minus){ |
||
6882 | |||
6883 | negflag=1; |
||
6884 | |||
6885 | } |
||
6886 | |||
6887 | #ifdef OPTVARCONST |
||
6888 | |||
6889 | // printf("type1=%d type2=%d\n",itok.type,itok2.type); |
||
6890 | |||
6891 | tok=tk_number; |
||
6892 | |||
6893 | } |
||
6894 | |||
6895 | #endif |
||
6896 | |||
6897 | case tk_number: |
||
6898 | |||
6899 | i=(int)doconstlongmath(); |
||
6900 | |||
6901 | ConstToReg(i,beg,r8); |
||
6902 | |||
6903 | case tk_rmnumber: |
||
6904 | |||
6905 | op66(r16); |
||
6906 | |||
6907 | if(itok.post==0)outseg(&itok,2); |
||
6908 | |||
6909 | op(beg*8+itok.rm); |
||
6910 | |||
6911 | if((itok.flag&f_extern)==0){ |
||
6912 | |||
6913 | if(am32&&itok.rm==rm_sib)outptr++; |
||
6914 | |||
6915 | outptr=ooutptr; |
||
6916 | |||
6917 | else setwordext(&itok.number); |
||
6918 | |||
6919 | outaddress(&itok); |
||
6920 | |||
6921 | break; |
||
6922 | |||
6923 | op66(r16); |
||
6924 | |||
6925 | (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
6926 | |||
6927 | nexttok(); |
||
6928 | |||
6929 | break; |
||
6930 | |||
6931 | i=4; |
||
6932 | |||
6933 | case tk_dwordvar: |
||
6934 | |||
6935 | case tk_intvar: |
||
6936 | |||
6937 | i++; |
||
6938 | |||
6939 | case tk_bytevar: |
||
6940 | |||
6941 | CheckAllMassiv(bufrm,i,&strinf); |
||
6942 | |||
6943 | op(0x8A); |
||
6944 | |||
6945 | outaddress(&itok); |
||
6946 | |||
6947 | ClearReg(beg%4); |
||
6948 | |||
6949 | case tk_doublevar: |
||
6950 | |||
6951 | case tk_floatvar: |
||
6952 | |||
6953 | if(beg>3){ |
||
6954 | |||
6955 | op(0xC0+beg+8*(beg-4)); |
||
6956 | |||
6957 | nexttok(); |
||
6958 | |||
6959 | break; |
||
6960 | |||
6961 | int vops; |
||
6962 | |||
6963 | if(i<=64)vops=r64; |
||
6964 | |||
6965 | if(i<=16)vops=r16; |
||
6966 | |||
6967 | if(beg>BX&&vops!=r8){ |
||
6968 | |||
6969 | op(0x50); |
||
6970 | |||
6971 | addESP+=vops==r16?2:4; |
||
6972 | |||
6973 | op(0x88); |
||
6974 | |||
6975 | op66(vops==r64?r32:vops); |
||
6976 | |||
6977 | op(0x58); |
||
6978 | |||
6979 | else bits2reg(beg,vops); |
||
6980 | |||
6981 | break; |
||
6982 | |||
6983 | if(beg!=(int)itok.number){ |
||
6984 | |||
6985 | op(0xC0+beg+(unsigned int)itok.number*8); |
||
6986 | |||
6987 | } |
||
6988 | |||
6989 | break; |
||
6990 | |||
6991 | case tk_reg: |
||
6992 | |||
6993 | if(beg!=(int)itok.number){ |
||
6994 | |||
6995 | op(0x89); |
||
6996 | |||
6997 | RegToReg(beg,itok.number,r8); |
||
6998 | |||
6999 | } |
||
7000 | |||
7001 | nexttok(); |
||
7002 | |||
7003 | case tk_seg: |
||
7004 | |||
7005 | op(0x8C); |
||
7006 | |||
7007 | nexttok(); |
||
7008 | |||
7009 | break; |
||
7010 | |||
7011 | case tk_id: |
||
7012 | |||
7013 | case tk_apiproc: |
||
7014 | |||
7015 | case tk_declare: |
||
7016 | |||
7017 | procdo(tk_byte); |
||
7018 | |||
7019 | op(0xc0+beg); |
||
7020 | |||
7021 | RegToReg(beg,AL,r8); |
||
7022 | |||
7023 | free(*ofsstr); |
||
7024 | |||
7025 | } |
||
7026 | |||
7027 | default: valueexpected(); nexttok(); return 0; |
||
7028 | |||
7029 | #ifdef OPTVARCONST |
||
7030 | |||
7031 | #endif |
||
7032 | |||
7033 | if(optimizespeed&&(chip==5||chip==6)){ |
||
7034 | |||
7035 | op(0xF0+beg); |
||
7036 | |||
7037 | op(0xFE); |
||
7038 | |||
7039 | } |
||
7040 | |||
7041 | op(0xF6); |
||
7042 | |||
7043 | } |
||
7044 | |||
7045 | } |
||
7046 | |||
7047 | } |
||
7048 | |||
7049 | void outaddress(ITOK *outtok) |
||
7050 | |||
7051 | int rm=outtok->rm; |
||
7052 | |||
7053 | if(rm==rm_d16){ |
||
7054 | |||
7055 | AddUndefOff(2,outtok->name); |
||
7056 | |||
7057 | } |
||
7058 | |||
7059 | } |
||
7060 | |||
7061 | rm&=rm_mod11; |
||
7062 | |||
7063 | else if(rm==rm_mod10){ |
||
7064 | |||
7065 | AddUndefOff(2,outtok->name); |
||
7066 | |||
7067 | } |
||
7068 | |||
7069 | } |
||
7070 | |||
7071 | } |
||
7072 | |||
7073 | else{ |
||
7074 | |||
7075 | if(outtok->post==UNDEF_OFSET){ |
||
7076 | |||
7077 | outtok->post=0; |
||
7078 | |||
7079 | outdword(outtok->number); |
||
7080 | |||
7081 | else{ |
||
7082 | |||
7083 | op(outtok->sib); |
||
7084 | |||
7085 | if(outtok->post==UNDEF_OFSET){ |
||
7086 | |||
7087 | outtok->post=0; |
||
7088 | |||
7089 | outdword(outtok->number); |
||
7090 | |||
7091 | } |
||
7092 | |||
7093 | if(rm==rm_mod11)internalerror(badadr); |
||
7094 | |||
7095 | if(outtok->post==UNDEF_OFSET){ |
||
7096 | |||
7097 | outtok->post=0; |
||
7098 | |||
7099 | outdword(outtok->number); |
||
7100 | |||
7101 | else if(rm==rm_mod01)op(outtok->number); |
||
7102 | |||
7103 | } |
||
7104 | |||
7105 | |||
7106 | |||
7107 | Обработка float |
||
7108 | |||
7109 | --------------------------------------------------*/ |
||
7110 | |||
7111 | { |
||
7112 | |||
7113 | unsigned int vop=0,rettype=tk_float,posiblret=tk_float,sign=0; |
||
7114 | |||
7115 | ITOK wtok; |
||
7116 | |||
7117 | int pointr=0; |
||
7118 | |||
7119 | int type=tk_floatvar; |
||
7120 | |||
7121 | rettype=posiblret=tk_double; |
||
7122 | |||
7123 | type=tk_doublevar; |
||
7124 | |||
7125 | wstr=strinf; |
||
7126 | |||
7127 | wtok=itok; |
||
7128 | |||
7129 | bufrm=NULL; |
||
7130 | |||
7131 | char *ofsstr=NULL; |
||
7132 | |||
7133 | switch(tok){ |
||
7134 | |||
7135 | getoperand(am32==TRUE?EAX:BX); |
||
7136 | |||
7137 | if(tok2==tk_assign){ |
||
7138 | |||
7139 | next=0; |
||
7140 | |||
7141 | } |
||
7142 | |||
7143 | if(itok2.type==tp_opperand){ //составное |
||
7144 | |||
7145 | if(OnlyNumber(rettype==tk_float?2:3)){ |
||
7146 | |||
7147 | itok.flag=(unsigned char)postnumflag; |
||
7148 | |||
7149 | goto numbertovar; |
||
7150 | |||
7151 | } |
||
7152 | |||
7153 | if(rettype==tk_char||rettype==tk_byte)doalmath(sign,&ofsstr); |
||
7154 | |||
7155 | else if(rettype==tk_long||rettype==tk_dword)do_e_axmath(sign,r32,&ofsstr); |
||
7156 | |||
7157 | } |
||
7158 | |||
7159 | switch(tok){ |
||
7160 | |||
7161 | numbertovar: |
||
7162 | |||
7163 | if(itok.rm==tk_double)itok.fnumber=itok.dnumber; |
||
7164 | |||
7165 | float temp=itok.number; |
||
7166 | |||
7167 | } |
||
7168 | |||
7169 | else{ |
||
7170 | |||
7171 | else if(itok.rm!=tk_double)itok.dnumber=itok.lnumber; |
||
7172 | |||
7173 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7174 | |||
7175 | op66(r32); |
||
7176 | |||
7177 | outseg(&wtok,2); |
||
7178 | |||
7179 | op(wtok.rm+0x20); |
||
7180 | |||
7181 | op(0); |
||
7182 | |||
7183 | else if(regoverstack&&short_ok(itok.number,TRUE)&&(itok.flag&f_reloc)==0){ |
||
7184 | |||
7185 | |||
7186 | |||
7187 | outseg(&wtok,2); |
||
7188 | |||
7189 | op(wtok.rm); |
||
7190 | |||
7191 | } |
||
7192 | |||
7193 | outseg(&wtok,2); |
||
7194 | |||
7195 | op(wtok.rm); |
||
7196 | |||
7197 | if((itok.flag&f_reloc)!=0)AddReloc(); |
||
7198 | |||
7199 | } |
||
7200 | |||
7201 | itok.lnumber>>=32; |
||
7202 | |||
7203 | compressoffset(&wtok); |
||
7204 | |||
7205 | break; |
||
7206 | |||
7207 | case tk_floatvar: |
||
7208 | |||
7209 | ITOK w1tok; |
||
7210 | |||
7211 | w1buf=bufrm; |
||
7212 | |||
7213 | w1tok=itok; |
||
7214 | |||
7215 | w1str=strinf; |
||
7216 | |||
7217 | getinto_e_ax(0,tok==tk_floatvar?tk_dwordvar:tk_qwordvar,&w1tok,w1buf,&w1str,r32); |
||
7218 | |||
7219 | if((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&wtok.sib==CODE32)){ |
||
7220 | |||
7221 | outseg(&wtok,1); |
||
7222 | |||
7223 | if(am32)outdword(wtok.number); |
||
7224 | |||
7225 | } |
||
7226 | |||
7227 | |||
7228 | |||
7229 | outseg(&wtok,2); |
||
7230 | |||
7231 | outaddress(&wtok); |
||
7232 | |||
7233 | itok.number+=4; |
||
7234 | |||
7235 | wtok.number+=4; |
||
7236 | |||
7237 | ITOK w1tok; |
||
7238 | |||
7239 | w1buf=bufrm; |
||
7240 | |||
7241 | w1tok=itok; |
||
7242 | |||
7243 | w1str=strinf; |
||
7244 | |||
7245 | getinto_e_ax(0,tk_qwordvar,&w1tok,w1buf,&w1str,r32); |
||
7246 | |||
7247 | getfromEAX=1; |
||
7248 | |||
7249 | default: |
||
7250 | |||
7251 | if((i=doeaxfloatmath(tk_fpust))==tk_fpust||i==tk_double){ |
||
7252 | |||
7253 | if(retrez==tk_floatvar||retrez==tk_doublevar){ |
||
7254 | |||
7255 | outseg(&wtok,2); |
||
7256 | |||
7257 | op(wtok.rm+0x18); |
||
7258 | |||
7259 | fwait3(); |
||
7260 | |||
7261 | else retrez=tk_fpust; |
||
7262 | |||
7263 | else getfromEAX=1; |
||
7264 | |||
7265 | } |
||
7266 | |||
7267 | if(getfromEAX){ |
||
7268 | |||
7269 | retrez=tk_reg32; |
||
7270 | |||
7271 | if((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&wtok.sib==CODE32)){ |
||
7272 | |||
7273 | outseg(&wtok,1); |
||
7274 | |||
7275 | if(am32)outdword(wtok.number); |
||
7276 | |||
7277 | } |
||
7278 | |||
7279 | CheckAllMassiv(wbuf,4,&wstr,&wtok); |
||
7280 | |||
7281 | outseg(&wtok,2); |
||
7282 | |||
7283 | outaddress(&wtok); |
||
7284 | |||
7285 | } |
||
7286 | |||
7287 | case tk_minusminus: |
||
7288 | |||
7289 | case tk_plusplus: |
||
7290 | |||
7291 | outword(0xe8d9); //fld1 |
||
7292 | |||
7293 | outseg(&wtok,2); //fadd var |
||
7294 | |||
7295 | op(wtok.rm+vop); |
||
7296 | |||
7297 | if(retrez==tk_floatvar||retrez==tk_doublevar){ |
||
7298 | |||
7299 | op(0xd9+addop); |
||
7300 | |||
7301 | outaddress(&wtok); |
||
7302 | |||
7303 | } |
||
7304 | |||
7305 | case tk_divequals: vop+=0x10; |
||
7306 | |||
7307 | case tk_multequals: vop+=8; |
||
7308 | |||
7309 | getoperand(am32==TRUE?EAX:BX); |
||
7310 | |||
7311 | if(tok==tk_number){ |
||
7312 | |||
7313 | (itok.rm==tk_double&&itok.dnumber==1.0)|| |
||
7314 | |||
7315 | if(vop==0||vop==0x28)goto incvar; |
||
7316 | |||
7317 | } |
||
7318 | |||
7319 | (itok.rm==tk_double&&itok.dnumber==0.0)||itok.lnumber==0){ |
||
7320 | |||
7321 | case 0x38: |
||
7322 | |||
7323 | break; |
||
7324 | |||
7325 | outword(0xEED9); //FLDZ |
||
7326 | |||
7327 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7328 | |||
7329 | op(0xd9+addop); |
||
7330 | |||
7331 | outaddress(&wtok); |
||
7332 | |||
7333 | } |
||
7334 | |||
7335 | } |
||
7336 | |||
7337 | } |
||
7338 | |||
7339 | } |
||
7340 | |||
7341 | doeaxfloatmath(tk_fpust); |
||
7342 | |||
7343 | next=0; |
||
7344 | |||
7345 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7346 | |||
7347 | op(0xd8+addop); |
||
7348 | |||
7349 | outaddress(&wtok); |
||
7350 | |||
7351 | outseg(&wtok,2); //fstp var |
||
7352 | |||
7353 | op(wtok.rm+0x18); |
||
7354 | |||
7355 | fwait3(); |
||
7356 | |||
7357 | } |
||
7358 | |||
7359 | switch(tok){ |
||
7360 | |||
7361 | if(rettype==tk_float){ |
||
7362 | |||
7363 | else if(itok.rm!=tk_float){ |
||
7364 | |||
7365 | *(float *)&itok.number=temp; |
||
7366 | |||
7367 | } |
||
7368 | |||
7369 | if(itok.rm==tk_float)itok.dnumber=itok.fnumber; |
||
7370 | |||
7371 | } |
||
7372 | |||
7373 | if(vop==0x38){ // div 22.12.05 22:10 |
||
7374 | |||
7375 | if(itok.rm==tk_float)itok.fnumber=1/itok.fnumber; |
||
7376 | |||
7377 | } |
||
7378 | |||
7379 | op66(r32); |
||
7380 | |||
7381 | op((am32==FALSE?0x06:0x05)); //fld |
||
7382 | |||
7383 | outword(0); |
||
7384 | |||
7385 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7386 | |||
7387 | op(0xd8+addop); |
||
7388 | |||
7389 | outaddress(&wtok); |
||
7390 | |||
7391 | outseg(&wtok,2); //fstp var |
||
7392 | |||
7393 | op(wtok.rm+0x18); |
||
7394 | |||
7395 | fwait3(); |
||
7396 | |||
7397 | break; |
||
7398 | |||
7399 | sign=2; |
||
7400 | |||
7401 | CheckAllMassiv(bufrm,4,&strinf); |
||
7402 | |||
7403 | op(0xd9+sign); |
||
7404 | |||
7405 | outaddress(&itok); |
||
7406 | |||
7407 | case tk_qwordvar: |
||
7408 | |||
7409 | i=0x28; |
||
7410 | |||
7411 | CheckAllMassiv(bufrm,8,&strinf); |
||
7412 | |||
7413 | op(0xdd+sign); |
||
7414 | |||
7415 | outaddress(&itok); |
||
7416 | |||
7417 | case tk_dwordvar: |
||
7418 | |||
7419 | op66(r32); //push 0L |
||
7420 | |||
7421 | if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; |
||
7422 | |||
7423 | CheckAllMassiv(bufrm,4,&strinf); |
||
7424 | |||
7425 | outseg(&itok,2); |
||
7426 | |||
7427 | op(itok.rm+0x30); |
||
7428 | |||
7429 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4; |
||
7430 | |||
7431 | fildq_stack(); |
||
7432 | |||
7433 | outseg(&wtok,2); //fsubr var |
||
7434 | |||
7435 | op(wtok.rm+vop); |
||
7436 | |||
7437 | if(optimizespeed||am32==0){ |
||
7438 | |||
7439 | op(8); |
||
7440 | |||
7441 | else{ |
||
7442 | |||
7443 | op(0x58); // pop EAX |
||
7444 | |||
7445 | addESP-=8; |
||
7446 | |||
7447 | outseg(&wtok,2); //fstp var |
||
7448 | |||
7449 | op(wtok.rm+0x18); |
||
7450 | |||
7451 | fwait3(); |
||
7452 | |||
7453 | RestoreBP(); |
||
7454 | |||
7455 | case tk_reg32: //добавить обработку интерпритации float, long |
||
7456 | |||
7457 | op66(r32); //push 0L |
||
7458 | |||
7459 | op66(r32); //push reg32 |
||
7460 | |||
7461 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; |
||
7462 | |||
7463 | fildq_stack(); |
||
7464 | |||
7465 | outseg(&wtok,2); //fsubr var |
||
7466 | |||
7467 | op(wtok.rm+vop); |
||
7468 | |||
7469 | if(optimizespeed||am32==0){ |
||
7470 | |||
7471 | op(8); |
||
7472 | |||
7473 | else{ |
||
7474 | |||
7475 | op(0x58); // pop EAX |
||
7476 | |||
7477 | addESP-=8; |
||
7478 | |||
7479 | outseg(&wtok,2); //fstp var |
||
7480 | |||
7481 | op(wtok.rm+0x18); |
||
7482 | |||
7483 | fwait3(); |
||
7484 | |||
7485 | RestoreBP(); |
||
7486 | |||
7487 | default: |
||
7488 | |||
7489 | CheckInitBP(); |
||
7490 | |||
7491 | op(0x50); |
||
7492 | |||
7493 | fld_stack(4+localsize); |
||
7494 | |||
7495 | RestoreBP(); |
||
7496 | |||
7497 | op(0x58); |
||
7498 | |||
7499 | goto endequals; |
||
7500 | |||
7501 | } |
||
7502 | |||
7503 | case tk_swap: |
||
7504 | |||
7505 | regdi=TRUE; |
||
7506 | |||
7507 | rbuf=bufrm; |
||
7508 | |||
7509 | if(am32!=FALSE&&wbuf!=NULL&&wstr.bufstr!=NULL)regdi=FALSE; |
||
7510 | |||
7511 | case tk_reg32: //добавить обработку интерпритации float, long |
||
7512 | |||
7513 | op66(r32); //push 0L |
||
7514 | |||
7515 | op66(r32); //push reg32 |
||
7516 | |||
7517 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; |
||
7518 | |||
7519 | fildq_stack(); |
||
7520 | |||
7521 | outseg(&wtok,2); //fld val |
||
7522 | |||
7523 | op(wtok.rm); |
||
7524 | |||
7525 | op(0xdb); |
||
7526 | |||
7527 | if(optimizespeed)outword(0x241c); //fistp ssdword[bp-8]/ssdword[esp] |
||
7528 | |||
7529 | outword(0x245C); |
||
7530 | |||
7531 | } |
||
7532 | |||
7533 | else{ |
||
7534 | |||
7535 | dob=8; |
||
7536 | |||
7537 | if(short_ok(localsize+dob,FALSE)==0){ |
||
7538 | |||
7539 | outword(-dob-localsize); |
||
7540 | |||
7541 | else{ |
||
7542 | |||
7543 | op(-dob-localsize); |
||
7544 | |||
7545 | } |
||
7546 | |||
7547 | op(0xd9+addop); |
||
7548 | |||
7549 | outaddress(&wtok); |
||
7550 | |||
7551 | op66(r32); // pop reg32 |
||
7552 | |||
7553 | if(!optimizespeed){ |
||
7554 | |||
7555 | op(0x58+(unsigned int)itok.number); |
||
7556 | |||
7557 | else{ |
||
7558 | |||
7559 | op(4); |
||
7560 | |||
7561 | addESP-=8; |
||
7562 | |||
7563 | break; |
||
7564 | |||
7565 | CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
7566 | |||
7567 | op(0xDB); |
||
7568 | |||
7569 | outaddress(&itok); |
||
7570 | |||
7571 | outseg(&wtok,2); //fld val |
||
7572 | |||
7573 | op(wtok.rm); |
||
7574 | |||
7575 | outseg(&itok,2);//fistp var |
||
7576 | |||
7577 | op(itok.rm+0x18); |
||
7578 | |||
7579 | outseg(&wtok,2); //fstp val |
||
7580 | |||
7581 | op(wtok.rm+0x18); |
||
7582 | |||
7583 | fwait3(); |
||
7584 | |||
7585 | case tk_qwordvar: |
||
7586 | |||
7587 | outseg(&itok,2); //fildq val |
||
7588 | |||
7589 | op(itok.rm+0x28); |
||
7590 | |||
7591 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7592 | |||
7593 | op(0xd9+addop); |
||
7594 | |||
7595 | outaddress(&wtok); |
||
7596 | |||
7597 | op(0xdf); |
||
7598 | |||
7599 | outaddress(&itok); |
||
7600 | |||
7601 | op(0xd9+addop); |
||
7602 | |||
7603 | outaddress(&wtok); |
||
7604 | |||
7605 | break; |
||
7606 | |||
7607 | CheckInitBP(); |
||
7608 | |||
7609 | outword(0x6a); |
||
7610 | |||
7611 | addESP+=4; |
||
7612 | |||
7613 | op66(r32); //push var |
||
7614 | |||
7615 | op(0xFF); |
||
7616 | |||
7617 | outaddress(&itok); |
||
7618 | |||
7619 | addESP+=4; |
||
7620 | |||
7621 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7622 | |||
7623 | op(0xd9+addop); |
||
7624 | |||
7625 | outaddress(&wtok); |
||
7626 | |||
7627 | outword(0xC483); |
||
7628 | |||
7629 | } |
||
7630 | |||
7631 | op(0x58); // pop EAX |
||
7632 | |||
7633 | } |
||
7634 | |||
7635 | outseg(&itok,2);//fistp var |
||
7636 | |||
7637 | op(itok.rm+0x18); |
||
7638 | |||
7639 | outseg(&wtok,2); //fstp val |
||
7640 | |||
7641 | op(wtok.rm+0x18); |
||
7642 | |||
7643 | fwait3(); |
||
7644 | |||
7645 | break; |
||
7646 | |||
7647 | if(rettype==tk_double){ |
||
7648 | |||
7649 | outseg(&itok,2); //fld val |
||
7650 | |||
7651 | op(itok.rm); |
||
7652 | |||
7653 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
7654 | |||
7655 | op(0xdd); |
||
7656 | |||
7657 | outaddress(&wtok); |
||
7658 | |||
7659 | op(0xd9); |
||
7660 | |||
7661 | outaddress(&itok); |
||
7662 | |||
7663 | op(0xdd); |
||
7664 | |||
7665 | outaddress(&wtok); |
||
7666 | |||
7667 | } |
||
7668 | |||
7669 | getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32); |
||
7670 | |||
7671 | op66(r32); |
||
7672 | |||
7673 | op(0x87); op(itok.rm); |
||
7674 | |||
7675 | goto getfromeax; |
||
7676 | |||
7677 | break; |
||
7678 | |||
7679 | if(rettype==tk_float){ |
||
7680 | |||
7681 | outseg(&itok,2); //fldq val |
||
7682 | |||
7683 | op(itok.rm); |
||
7684 | |||
7685 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
7686 | |||
7687 | op(0xd9); |
||
7688 | |||
7689 | outaddress(&wtok); |
||
7690 | |||
7691 | op(0xdd); |
||
7692 | |||
7693 | outaddress(&itok); |
||
7694 | |||
7695 | op(0xd9); |
||
7696 | |||
7697 | outaddress(&wtok); |
||
7698 | |||
7699 | } |
||
7700 | |||
7701 | getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32); |
||
7702 | |||
7703 | op66(r32); |
||
7704 | |||
7705 | op(0x87); op(itok.rm); |
||
7706 | |||
7707 | goto getfromeax; |
||
7708 | |||
7709 | break; |
||
7710 | |||
7711 | if(itok.number>6)fpustdestroed(); |
||
7712 | |||
7713 | outseg(&wtok,2); //fld val |
||
7714 | |||
7715 | op(wtok.rm); |
||
7716 | |||
7717 | op(0xD9); |
||
7718 | |||
7719 | outseg(&wtok,2); //fstp val |
||
7720 | |||
7721 | op(wtok.rm+0x18); |
||
7722 | |||
7723 | break; |
||
7724 | |||
7725 | } |
||
7726 | |||
7727 | default: operatorexpected(); break; |
||
7728 | |||
7729 | if(next)nexttok(); |
||
7730 | |||
7731 | if(cpu<3)cpu=3; |
||
7732 | |||
7733 | } |
||
7734 | |||
7735 | void fildq2_stack(int size) |
||
7736 | |||
7737 | op(0xdf); |
||
7738 | |||
7739 | else{ |
||
7740 | |||
7741 | op(0xAE); |
||
7742 | |||
7743 | } |
||
7744 | |||
7745 | op(0x6E); |
||
7746 | |||
7747 | } |
||
7748 | |||
7749 | } |
||
7750 | |||
7751 | void fildq_stack() |
||
7752 | |||
7753 | fildq2_stack(localsize+8); |
||
7754 | |||
7755 | |||
7756 | |||
7757 | { |
||
7758 | |||
7759 | else{ |
||
7760 | |||
7761 | op(0x9E); |
||
7762 | |||
7763 | } |
||
7764 | |||
7765 | op(0x5E); |
||
7766 | |||
7767 | } |
||
7768 | |||
7769 | } |
||
7770 | |||
7771 | void fistp_stack(int addop) |
||
7772 | |||
7773 | op(0xDB+addop); |
||
7774 | |||
7775 | } |
||
7776 | |||
7777 | void fld_stack(int size) |
||
7778 | |||
7779 | if(am32)outword(0x2404); //fld ssdword[ebp+2]/ssdword[esp] |
||
7780 | |||
7781 | if(short_ok(size,FALSE)==0){ |
||
7782 | |||
7783 | outword(-size); |
||
7784 | |||
7785 | else{ |
||
7786 | |||
7787 | op(-size); |
||
7788 | |||
7789 | } |
||
7790 | |||
7791 | |||
7792 | |||
7793 | //конвертация float в число |
||
7794 | |||
7795 | CheckInitBP(); |
||
7796 | |||
7797 | fld_stack(4+localsize+addop); |
||
7798 | |||
7799 | RestoreBP(); |
||
7800 | |||
7801 | op66(r32); |
||
7802 | |||
7803 | if(cpu<3)cpu=3; |
||
7804 | |||
7805 | |||
7806 | |||
7807 | { |
||
7808 | |||
7809 | op66(r32); |
||
7810 | |||
7811 | if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; |
||
7812 | |||
7813 | CheckAllMassiv(bufrm,4+addop,&strinf,&itok,reg1,reg2); |
||
7814 | |||
7815 | op(0xd9+addop); |
||
7816 | |||
7817 | outaddress(&itok); |
||
7818 | |||
7819 | fwait3(); |
||
7820 | |||
7821 | op(0x58+reg); //pop reg |
||
7822 | |||
7823 | if(cpu<3)cpu=3; |
||
7824 | |||
7825 | } |
||
7826 | |||
7827 | void byteinstack(int *numstak,int *nums) |
||
7828 | |||
7829 | CheckInitBP(); |
||
7830 | |||
7831 | op66(r16); |
||
7832 | |||
7833 | outword(0xC031); //xor ax,ax |
||
7834 | |||
7835 | op(0x8A); |
||
7836 | |||
7837 | else{ |
||
7838 | |||
7839 | op(0xf); |
||
7840 | |||
7841 | else op(0xbe); |
||
7842 | |||
7843 | op(itok.rm); |
||
7844 | |||
7845 | op66(r16); |
||
7846 | |||
7847 | *numstak+=2; |
||
7848 | |||
7849 | fld_stack(*nums+*numstak); |
||
7850 | |||
7851 | |||
7852 | |||
7853 | { |
||
7854 | |||
7855 | op66(tok==tk_reg32?r32:r16); |
||
7856 | |||
7857 | if(optimizespeed&&chip>3&&chip<7&&itok.number!=AL&&itok.number!=AH){ |
||
7858 | |||
7859 | op(0x88); |
||
7860 | |||
7861 | } |
||
7862 | |||
7863 | else{ |
||
7864 | |||
7865 | op(0xC0+itok.number); |
||
7866 | |||
7867 | itok.number=0; |
||
7868 | |||
7869 | else outword(0x6a); //push 0 |
||
7870 | |||
7871 | op(0x50+itok.number); //push AX |
||
7872 | |||
7873 | op(0xDB); |
||
7874 | |||
7875 | addESP+=4; |
||
7876 | |||
7877 | } |
||
7878 | |||
7879 | op(0xdf); |
||
7880 | |||
7881 | addESP+=2; |
||
7882 | |||
7883 | } |
||
7884 | |||
7885 | *numstak+=8; |
||
7886 | |||
7887 | fildq2_stack(*nums+*numstak); |
||
7888 | |||
7889 | } |
||
7890 | |||
7891 | void wordinstack(int *numstak,int *nums) |
||
7892 | |||
7893 | CheckInitBP(); |
||
7894 | |||
7895 | outword(0x6a); //push 0 |
||
7896 | |||
7897 | CheckAllMassiv(bufrm,tok==tk_wordvar?2:4,&strinf); |
||
7898 | |||
7899 | outseg(&itok,2); //push var |
||
7900 | |||
7901 | op(itok.rm+0x30); |
||
7902 | |||
7903 | if(tok==tk_wordvar){ |
||
7904 | |||
7905 | addESP+=4; |
||
7906 | |||
7907 | fld_stack(*nums+*numstak); |
||
7908 | |||
7909 | else{ |
||
7910 | |||
7911 | *numstak+=8; |
||
7912 | |||
7913 | } |
||
7914 | |||
7915 | |||
7916 | |||
7917 | { |
||
7918 | |||
7919 | outseg(&itok,2); //fild intvar |
||
7920 | |||
7921 | else if(tok==tk_floatvar||tok==tk_doublevar)op(0xd9+addop); |
||
7922 | |||
7923 | op(itok.rm+(tok==tk_qwordvar?0x28:0)); |
||
7924 | |||
7925 | } |
||
7926 | |||
7927 | int doeaxfloatmath(int itreturn,int reg,int addop) |
||
7928 | |||
7929 | int vop,negflag=0,next,numstak=0; |
||
7930 | |||
7931 | int i=0; |
||
7932 | |||
7933 | int ols; |
||
7934 | |||
7935 | nums+=localsize; |
||
7936 | |||
7937 | if(tok==tk_minus){ |
||
7938 | |||
7939 | negflag=1; |
||
7940 | |||
7941 | } |
||
7942 | |||
7943 | if(tok==tk_number){ |
||
7944 | |||
7945 | if(addop==0/*itok.rm==tk_float*/){ |
||
7946 | |||
7947 | itok.rm=tk_float; |
||
7948 | |||
7949 | else{ |
||
7950 | |||
7951 | itok.rm=tk_double; |
||
7952 | |||
7953 | next=0; |
||
7954 | |||
7955 | // if(itok.rm==tk_float&&addop==4)itok.dnumber=itok.fnumber; |
||
7956 | |||
7957 | if(itreturn==tk_stackstart){ |
||
7958 | |||
7959 | lnumber=itok.lnumber; |
||
7960 | |||
7961 | } |
||
7962 | |||
7963 | op66(r32); |
||
7964 | |||
7965 | op(0x6A); |
||
7966 | |||
7967 | } |
||
7968 | |||
7969 | op(0x68); |
||
7970 | |||
7971 | } |
||
7972 | |||
7973 | if(i==1)break; |
||
7974 | |||
7975 | } |
||
7976 | |||
7977 | } |
||
7978 | |||
7979 | MovRegNum(r32,0,itok.number,reg); |
||
7980 | |||
7981 | } |
||
7982 | |||
7983 | MovRegNum(r32,0,itok.number,reg&255); |
||
7984 | |||
7985 | return itreturn; |
||
7986 | |||
7987 | } |
||
7988 | |||
7989 | if(itreturn==tk_stackstart&&(!am32)){ |
||
7990 | |||
7991 | op(0x50); //push eax |
||
7992 | |||
7993 | op66(r32); |
||
7994 | |||
7995 | } |
||
7996 | |||
7997 | outword(0xe589);//mov bp,sp |
||
7998 | |||
7999 | localsize=-6-addop; |
||
8000 | |||
8001 | if(next==0)goto casenumber; |
||
8002 | |||
8003 | case tk_number: |
||
8004 | |||
8005 | // printf("rm=%d %e %e %08X\n",itok.rm,itok.fnumber,itok.dnumber,itok.number); |
||
8006 | |||
8007 | (itok.rm==tk_double&&itok.dnumber==1.0)|| |
||
8008 | |||
8009 | outword(0xE8D9); //FLD1 |
||
8010 | |||
8011 | } |
||
8012 | |||
8013 | (itok.rm==tk_double&&itok.dnumber==0.0)||itok.lnumber==0){ |
||
8014 | |||
8015 | break; |
||
8016 | |||
8017 | op(0xD9+(itok.rm==tk_float?0:4)); |
||
8018 | |||
8019 | AddFloatConst(itok.lnumber,itok.rm); |
||
8020 | |||
8021 | if(am32)outword(0); |
||
8022 | |||
8023 | case tk_at: |
||
8024 | |||
8025 | macros(tk_fpust); |
||
8026 | |||
8027 | case tk_ID: |
||
8028 | |||
8029 | case tk_proc: |
||
8030 | |||
8031 | case tk_declare: |
||
8032 | |||
8033 | int onums; |
||
8034 | |||
8035 | nums=-(int)localsize; |
||
8036 | |||
8037 | nums=onums; |
||
8038 | |||
8039 | nexttok(); |
||
8040 | |||
8041 | } |
||
8042 | |||
8043 | case tk_qwordvar: |
||
8044 | |||
8045 | i=4; |
||
8046 | |||
8047 | case tk_longvar: |
||
8048 | |||
8049 | intinstack(i); |
||
8050 | |||
8051 | case tk_dwordvar: |
||
8052 | |||
8053 | wordinstack(&numstak,&nums); |
||
8054 | |||
8055 | case tk_charvar: |
||
8056 | |||
8057 | byteinstack(&numstak,&nums); |
||
8058 | |||
8059 | case tk_beg: |
||
8060 | |||
8061 | case tk_reg: |
||
8062 | |||
8063 | break; |
||
8064 | |||
8065 | if(itok.number){ |
||
8066 | |||
8067 | op(0xC8+itok.number); |
||
8068 | |||
8069 | break; |
||
8070 | |||
8071 | } |
||
8072 | |||
8073 | outword(0xe0d9); //fchs |
||
8074 | |||
8075 | } |
||
8076 | |||
8077 | while(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){ |
||
8078 | |||
8079 | vop=0; |
||
8080 | |||
8081 | switch(tok){ |
||
8082 | |||
8083 | case tk_divminus: negflag=1; |
||
8084 | |||
8085 | case tk_minus: vop+=0x20; |
||
8086 | |||
8087 | case tk_mult: vop+=8; |
||
8088 | |||
8089 | |||
8090 | |||
8091 | case tk_number: |
||
8092 | |||
8093 | itok.dnumber=itok.lnumber; |
||
8094 | |||
8095 | } |
||
8096 | |||
8097 | (itok.rm==tk_double&&itok.dnumber==1.0)){ |
||
8098 | |||
8099 | if(vop==0||vop==0x28){ // + - |
||
8100 | |||
8101 | op(0xDE); |
||
8102 | |||
8103 | } |
||
8104 | |||
8105 | } |
||
8106 | |||
8107 | |||
8108 | |||
8109 | vop=8; //mult |
||
8110 | |||
8111 | else itok.dnumber=1/itok.dnumber; |
||
8112 | |||
8113 | if(/*vop==0x38||*/vop==0x28)vop-=8; |
||
8114 | |||
8115 | op((am32==FALSE?0x06:0x05)+vop); |
||
8116 | |||
8117 | outword(0); |
||
8118 | |||
8119 | break; |
||
8120 | |||
8121 | i=4; |
||
8122 | |||
8123 | if(vop==0x38||vop==0x28)vop-=8; |
||
8124 | |||
8125 | outseg(&itok,2); //fsubr var |
||
8126 | |||
8127 | op(itok.rm+vop); |
||
8128 | |||
8129 | break; |
||
8130 | |||
8131 | case tk_intvar: |
||
8132 | |||
8133 | outseg(&itok,2); //fsubr var |
||
8134 | |||
8135 | if(vop==0x38||vop==0x28)vop-=8; |
||
8136 | |||
8137 | outaddress(&itok); |
||
8138 | |||
8139 | case tk_qwordvar: |
||
8140 | |||
8141 | op(0xde); |
||
8142 | |||
8143 | break; |
||
8144 | |||
8145 | case tk_wordvar: |
||
8146 | |||
8147 | op(0xde); |
||
8148 | |||
8149 | break; |
||
8150 | |||
8151 | case tk_reg32: |
||
8152 | |||
8153 | reginstack(&numstak,&nums); |
||
8154 | |||
8155 | op(0xC1+vop);//fsubpr st1 |
||
8156 | |||
8157 | case tk_charvar: |
||
8158 | |||
8159 | byteinstack(&numstak,&nums); |
||
8160 | |||
8161 | op(0xC1+vop);//fsubpr st1 |
||
8162 | |||
8163 | case tk_fpust: |
||
8164 | |||
8165 | op(0xd8); |
||
8166 | |||
8167 | break; |
||
8168 | |||
8169 | } |
||
8170 | |||
8171 | default: illegalfloat(); break; |
||
8172 | |||
8173 | if(negflag){ |
||
8174 | |||
8175 | negflag=0; |
||
8176 | |||
8177 | if(next)nexttok(); |
||
8178 | |||
8179 | if(tok==tk_eof)unexpectedeof(); |
||
8180 | |||
8181 | if(!am32){ |
||
8182 | |||
8183 | outword(0x025e); //fstp ssdword[bp+2] |
||
8184 | |||
8185 | } |
||
8186 | |||
8187 | if(numstak<4){ |
||
8188 | |||
8189 | op(0x50); //push eax |
||
8190 | |||
8191 | } |
||
8192 | |||
8193 | if(addop){ |
||
8194 | |||
8195 | op66(r32); |
||
8196 | |||
8197 | addESP+=4; |
||
8198 | |||
8199 | else numstak-=4; |
||
8200 | |||
8201 | op(0xD9+addop); |
||
8202 | |||
8203 | else{ |
||
8204 | |||
8205 | op(numstak); |
||
8206 | |||
8207 | } |
||
8208 | |||
8209 | } |
||
8210 | |||
8211 | i=4; |
||
8212 | |||
8213 | if(numstak |
||
8214 | |||
8215 | op(0x50); //push eax |
||
8216 | |||
8217 | op66(r32); |
||
8218 | |||
8219 | } |
||
8220 | |||
8221 | addESP+=i; |
||
8222 | |||
8223 | op(itreturn==tk_reg32?0xDB:0xDF); |
||
8224 | |||
8225 | fistp2_stack(localsize+numstak); |
||
8226 | |||
8227 | if(itreturn==tk_reg64){ |
||
8228 | |||
8229 | op(0x58); //pop EAX |
||
8230 | |||
8231 | op(0x58+EDX); //pop EDX |
||
8232 | |||
8233 | else{ |
||
8234 | |||
8235 | op(0x58+reg); //pop reg |
||
8236 | |||
8237 | numstak-=i; |
||
8238 | |||
8239 | } |
||
8240 | |||
8241 | localsize=ols; |
||
8242 | |||
8243 | initBP--; |
||
8244 | |||
8245 | else if(numstak){ |
||
8246 | |||
8247 | outword(0xC483); |
||
8248 | |||
8249 | } |
||
8250 | |||
8251 | outword(0xC481); |
||
8252 | |||
8253 | } |
||
8254 | |||
8255 | } |
||
8256 | |||
8257 | nums-=localsize; |
||
8258 | |||
8259 | } |
||
8260 | |||
8261 | void float2stack(int num) |
||
8262 | |||
8263 | outword(0xC0DD); |
||
8264 | |||
8265 | // if(num>6)fpustdestroed(); |
||
8266 | |||
8267 | doeaxfloatmath(tk_fpust); |
||
8268 | |||
8269 | op(0xD9); |
||
8270 | |||
8271 | } |
||
8272 | |||
8273 | |||
8274 | |||
8275 | { |
||
8276 | |||
8277 | nexttok(); |
||
8278 | |||
8279 | case tk_assign: //= |
||
8280 | |||
8281 | float2stack(num); |
||
8282 | |||
8283 | case tk_divequals: vop+=0x10; |
||
8284 | |||
8285 | case tk_multequals: vop+=8; |
||
8286 | |||
8287 | getoperand(am32==TRUE?EAX:BX); |
||
8288 | |||
8289 | // doeaxfloatmath(tk_fpust); |
||
8290 | |||
8291 | op(0xC0+vop+num);//fsubpr st |
||
8292 | |||
8293 | case tk_swap: |
||
8294 | |||
8295 | switch(tok){ |
||
8296 | |||
8297 | op(0xD9); |
||
8298 | |||
8299 | op(0xD9); |
||
8300 | |||
8301 | op(0xD9); |
||
8302 | |||
8303 | break; |
||
8304 | |||
8305 | vop=4; |
||
8306 | |||
8307 | CheckAllMassiv(bufrm,4,&strinf); |
||
8308 | |||
8309 | op(0xd9+vop); |
||
8310 | |||
8311 | outaddress(&itok); |
||
8312 | |||
8313 | op(0xC8+num+1); |
||
8314 | |||
8315 | op(0xd9+vop); |
||
8316 | |||
8317 | outaddress(&itok); |
||
8318 | |||
8319 | default: |
||
8320 | |||
8321 | break; |
||
8322 | |||
8323 | |||
8324 | |||
8325 | default: |
||
8326 | |||
8327 | } |
||
8328 | |||
8329 | |||
8330 | |||
8331 | { |
||
8332 | |||
8333 | Leave(); |
||
8334 | |||
8335 | } |
||
8336 | |||
8337 | |||
8338 | |||
8339 | { |
||
8340 | |||
8341 | op(0x55); //push bp |
||
8342 | |||
8343 | initBP=2; |
||
8344 | |||
8345 | } |
||
8346 | |||
8347 | void AddReloc(int segm) |
||
8348 | |||
8349 | if(FixUp!=FALSE){ |
||
8350 | |||
8351 | if(segm==DS){ |
||
8352 | |||
8353 | (postbuf+posts)->loc=outptrdata; |
||
8354 | |||
8355 | else{ |
||
8356 | |||
8357 | (postbuf+posts)->loc=outptr; |
||
8358 | |||
8359 | posts++; |
||
8360 | |||
8361 | postnumflag&=(~f_reloc); |
||
8362 | |||
8363 | |||
8364 | |||
8365 | { |
||
8366 | |||
8367 | } |
||
8368 | |||
8369 | void AddFloatConst(long long fnumber,int type) |
||
8370 | |||
8371 | unsigned int i; |
||
8372 | |||
8373 | for(i=0;i |
||
8374 | |||
8375 | ofs=(floatnum+i)->ofs; |
||
8376 | |||
8377 | if(*(long *)&fnumber==(floatnum+i)->num[0])goto endp; |
||
8378 | |||
8379 | else if(*(double *)&fnumber==(floatnum+i)->dnum)goto endp; |
||
8380 | |||
8381 | } |
||
8382 | |||
8383 | floatnum=(LISTFLOAT *)MALLOC(sizeof(LISTFLOAT)*STEPFLOATCONST); |
||
8384 | |||
8385 | // memset(floatnum,0,sizeof(LISTFLOAT)*STEPFLOATCONST); |
||
8386 | |||
8387 | else if((numfloatconst+1)==maxnumfloatconst){ |
||
8388 | |||
8389 | maxnumfloatconst+=STEPFLOATCONST; |
||
8390 | |||
8391 | numfloatconst++; |
||
8392 | |||
8393 | ofs=(floatnum+i)->ofs=ofsfloatlist; |
||
8394 | |||
8395 | else (floatnum+i)->dnum=*(double *)&fnumber; |
||
8396 | |||
8397 | endp: |
||
8398 | |||
8399 | (postbuf+posts)->type=POST_FLOATNUM; |
||
8400 | |||
8401 | (postbuf+posts)->num=ofs; |
||
8402 | |||
8403 | } |
||
8404 | |||
8405 | void setwordext(long *id) |
||
8406 | |||
8407 | CheckPosts(); |
||
8408 | |||
8409 | (postbuf+posts)->loc=outptr; |
||
8410 | |||
8411 | *id>>=16; //ее значение |
||
8412 | |||
8413 | } |
||
8414 | |||
8415 | void setwordpost(ITOK *stok) /* for post word num setting */ |
||
8416 | |||
8417 | CheckPosts(); |
||
8418 | |||
8419 | (postbuf+posts)->type=(unsigned short)(am32==0?DIN_VAR:DIN_VAR32); |
||
8420 | |||
8421 | // printf("rec=%08X\n",stok->rec); |
||
8422 | |||
8423 | (postbuf+posts)->num=(int)stok->rec;//02.09.05 17:11 ->right; |
||
8424 | |||
8425 | else (postbuf+posts)->num=(int)stok->rec; |
||
8426 | |||
8427 | else if(stok->post>=CODE_SIZE&&stok->post<=STACK_SIZE32)(postbuf+posts)->type=stok->post; |
||
8428 | |||
8429 | (postbuf+posts)->loc=outptr; |
||
8430 | |||
8431 | } |
||
8432 | |||
8433 | void MovRegNum(int razr,int relocf,unsigned long number,int reg) |
||
8434 | |||
8435 | unsigned long num; |
||
8436 | |||
8437 | op66(razr); |
||
8438 | |||
8439 | if(number!=0&&GetRegNumber(reg,&num,razr)==reg){ |
||
8440 | |||
8441 | if(num==number)return; |
||
8442 | |||
8443 | num=number-num; |
||
8444 | |||
8445 | op(0x40+reg); //inc reg |
||
8446 | |||
8447 | } |
||
8448 | |||
8449 | op(0x40+reg); //inc reg |
||
8450 | |||
8451 | op(0x40+reg); //inc reg |
||
8452 | |||
8453 | } |
||
8454 | |||
8455 | op(0x83); |
||
8456 | |||
8457 | |||
8458 | |||
8459 | } |
||
8460 | |||
8461 | else{ |
||
8462 | |||
8463 | if(num==1){ |
||
8464 | |||
8465 | return; |
||
8466 | |||
8467 | if(num==2){ |
||
8468 | |||
8469 | op66(razr); |
||
8470 | |||
8471 | return; |
||
8472 | |||
8473 | if(razr==r32&&short_ok(num,TRUE)){ |
||
8474 | |||
8475 | op(0xE8+reg); |
||
8476 | |||
8477 | return; |
||
8478 | |||
8479 | } |
||
8480 | |||
8481 | if((nreg=GetNumberR(reg,&num,razr,number))!=NOINREG){ |
||
8482 | |||
8483 | if(num==number){ |
||
8484 | |||
8485 | op(128+64+nreg*8+reg); |
||
8486 | |||
8487 | } |
||
8488 | |||
8489 | op(0x89); |
||
8490 | |||
8491 | op66(razr); |
||
8492 | |||
8493 | return; |
||
8494 | |||
8495 | else{ |
||
8496 | |||
8497 | op(0x89); |
||
8498 | |||
8499 | op66(razr); |
||
8500 | |||
8501 | return; |
||
8502 | |||
8503 | } |
||
8504 | |||
8505 | ConstToReg(number,reg,razr); |
||
8506 | |||
8507 | op(0x31); op(0xC0+reg*9); |
||
8508 | |||
8509 | else if((long)number==-1&&razr==r32){ |
||
8510 | |||
8511 | op(0xC8+reg); |
||
8512 | |||
8513 | } |
||
8514 | |||
8515 | op(0x31); op(0xC0+reg*9); //xor reg,reg |
||
8516 | |||
8517 | op(0x40+reg); //inc reg |
||
8518 | |||
8519 | else if(regoverstack&&razr==r32&&short_ok(number,TRUE)){ |
||
8520 | |||
8521 | op(number); //push short number |
||
8522 | |||
8523 | op(0x58+reg); |
||
8524 | |||
8525 | else goto stdmov; |
||
8526 | |||
8527 | else{ |
||
8528 | |||
8529 | op(0xB8+reg); // MOV reg,# |
||
8530 | |||
8531 | razr==r16?outword(number):outdword(number); |
||
8532 | |||
8533 | } |
||
8534 | |||
8535 | |||
8536 | |||
8537 | { |
||
8538 | |||
8539 | if(optimizespeed&&(chip==5||chip==6)){ |
||
8540 | |||
8541 | op(0xF0+reg); |
||
8542 | |||
8543 | op66(razr); |
||
8544 | |||
8545 | } |
||
8546 | |||
8547 | op(0xF7); |
||
8548 | |||
8549 | } |
||
8550 | |||
8551 | } |
||
8552 | |||
8553 | int RshiftReg(int razr,int reg,int sign) |
||
8554 | |||
8555 | char *ofsstr=NULL; |
||
8556 | |||
8557 | if((unsigned int)itok.number==1){ |
||
8558 | |||
8559 | op(0xD1); op(0xE8+reg+sign); // SHR reg,1 |
||
8560 | |||
8561 | else if((unsigned int)itok.number!=0){ |
||
8562 | |||
8563 | if(reg==ECX)return FALSE; |
||
8564 | |||
8565 | } |
||
8566 | |||
8567 | op66(razr); |
||
8568 | |||
8569 | op(0xe8+reg+sign); // SHR reg,imm8 |
||
8570 | |||
8571 | if(cpu<2)cpu=2; |
||
8572 | |||
8573 | } |
||
8574 | |||
8575 | } |
||
8576 | |||
8577 | else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==CL){ |
||
8578 | |||
8579 | goto rshift; |
||
8580 | |||
8581 | else{ |
||
8582 | |||
8583 | getintobeg(CL,&ofsstr); |
||
8584 | |||
8585 | rshift: |
||
8586 | |||
8587 | op(0xD3); |
||
8588 | |||
8589 | } |
||
8590 | |||
8591 | } |
||
8592 | |||
8593 | int CheckMinusNum() |
||
8594 | |||
8595 | if(tok==tk_minus&&tok2==tk_number){ |
||
8596 | |||
8597 | if(itok.rm==tk_float)itok.number|=0x80000000; |
||
8598 | |||
8599 | else itok.lnumber=-itok.lnumber; |
||
8600 | |||
8601 | } |
||
8602 | |||
8603 | } |
||
8604 | |||
8605 | int MulReg(int reg,int razr) |
||
8606 | |||
8607 | int next=1,i=0; |
||
8608 | |||
8609 | char *ofsstr=NULL; |
||
8610 | |||
8611 | case tk_number: |
||
8612 | |||
8613 | break; |
||
8614 | |||
8615 | case tk_undefofs: |
||
8616 | |||
8617 | op66(razr); |
||
8618 | |||
8619 | op(0xc0+reg*9); |
||
8620 | |||
8621 | else AddUndefOff(0,itok.name); |
||
8622 | |||
8623 | break; |
||
8624 | |||
8625 | if(chip<2&&razr==r16)regmathoperror(); |
||
8626 | |||
8627 | op(0x69); |
||
8628 | |||
8629 | AddApiToPost(itok.number); |
||
8630 | |||
8631 | case tk_doublevar: |
||
8632 | |||
8633 | case tk_floatvar: |
||
8634 | |||
8635 | Float2reg32(i,ii); |
||
8636 | |||
8637 | outword(0xAF0F); |
||
8638 | |||
8639 | warningreg(regs[1][i]); |
||
8640 | |||
8641 | case tk_qwordvar: |
||
8642 | |||
8643 | case tk_longvar: |
||
8644 | |||
8645 | i+=4; |
||
8646 | |||
8647 | case tk_intvar: |
||
8648 | |||
8649 | if(chip<2)regmathoperror(); |
||
8650 | |||
8651 | i=2; |
||
8652 | |||
8653 | CheckAllMassiv(bufrm,i,&strinf); |
||
8654 | |||
8655 | outseg(&itok,3); |
||
8656 | |||
8657 | op(reg*8+itok.rm); |
||
8658 | |||
8659 | break; |
||
8660 | |||
8661 | int vops,reg2s; |
||
8662 | |||
8663 | if(i<=64)vops=r64; |
||
8664 | |||
8665 | if(i<=16)vops=r16; |
||
8666 | |||
8667 | reg2s=CX; |
||
8668 | |||
8669 | bits2reg(reg2s,vops); |
||
8670 | |||
8671 | warningreg(regs[vops/2-1][reg2s]); |
||
8672 | |||
8673 | goto defreg32; |
||
8674 | |||
8675 | if(chip<2)regmathoperror(); |
||
8676 | |||
8677 | op66(r32); |
||
8678 | |||
8679 | if(itok.number==reg){ |
||
8680 | |||
8681 | itok.number=EAX; |
||
8682 | |||
8683 | else op(0xC0+itok.number*9); |
||
8684 | |||
8685 | } |
||
8686 | |||
8687 | defreg32: |
||
8688 | |||
8689 | outword(0xAF0F); |
||
8690 | |||
8691 | break; |
||
8692 | |||
8693 | case tk_id: |
||
8694 | |||
8695 | case tk_apiproc: |
||
8696 | |||
8697 | case tk_declare: |
||
8698 | |||
8699 | i=EAX; |
||
8700 | |||
8701 | case tk_seg: |
||
8702 | |||
8703 | case tk_beg: |
||
8704 | |||
8705 | case tk_rmnumber: |
||
8706 | |||
8707 | i=EDX; |
||
8708 | |||
8709 | getintoreg_32(i,razr,0,&ofsstr,FALSE); |
||
8710 | |||
8711 | op66(razr); |
||
8712 | |||
8713 | op(0xC0+reg*8+i); |
||
8714 | |||
8715 | if(i!=EDX)warningreg(regs[razr/2-1][i]); |
||
8716 | |||
8717 | break; |
||
8718 | |||
8719 | } |
||
8720 | |||
8721 | } |
||
8722 | |||
8723 | void DivMod(int vop,int sign,int razr,int expand) |
||
8724 | |||
8725 | int i,next; |
||
8726 | |||
8727 | if(tok==tk_bits){ |
||
8728 | |||
8729 | if(i<=64)next=r64; |
||
8730 | |||
8731 | if(i<=16)next=r16; |
||
8732 | |||
8733 | itok.number=CX; |
||
8734 | |||
8735 | ClearReg(CX); |
||
8736 | |||
8737 | tok=(razr==r16?tk_reg:tk_reg32); |
||
8738 | |||
8739 | i=0; |
||
8740 | |||
8741 | if(tok==tk_number){ |
||
8742 | |||
8743 | if(vop){ //% |
||
8744 | |||
8745 | if(itok.number==0)DevideZero(); |
||
8746 | |||
8747 | itok.number--; |
||
8748 | |||
8749 | else if(short_ok(itok.number,razr/2-1)){ |
||
8750 | |||
8751 | outword(0xE083); |
||
8752 | |||
8753 | } |
||
8754 | |||
8755 | op66(razr); |
||
8756 | |||
8757 | razr==r16?outword((unsigned int)itok.number):outdword(itok.number); |
||
8758 | |||
8759 | setzeroflag=TRUE; |
||
8760 | |||
8761 | else{ |
||
8762 | |||
8763 | if(!expand)ClearDX(razr,sign); |
||
8764 | |||
8765 | setzeroflag=FALSE; |
||
8766 | |||
8767 | } |
||
8768 | |||
8769 | if((itok.flag&f_reloc)!=0)goto divin; |
||
8770 | |||
8771 | case 0: |
||
8772 | |||
8773 | break; |
||
8774 | |||
8775 | case 2: |
||
8776 | |||
8777 | op66(razr); |
||
8778 | |||
8779 | outdword(0x01d0ac0f); //shrd ax,dx,1 |
||
8780 | |||
8781 | } |
||
8782 | |||
8783 | outword(0xead1); //shr dx,1 rcr ax,1 |
||
8784 | |||
8785 | outword(0xd8d1); |
||
8786 | |||
8787 | } |
||
8788 | |||
8789 | ClearReg(DX); |
||
8790 | |||
8791 | } |
||
8792 | |||
8793 | if(sign)outword(0xF8D1);// SAR AX,1 |
||
8794 | |||
8795 | setzeroflag=TRUE; |
||
8796 | |||
8797 | break; |
||
8798 | |||
8799 | vop=caselong(itok.number); |
||
8800 | |||
8801 | if(expand==TRUE){ |
||
8802 | |||
8803 | op66(razr); |
||
8804 | |||
8805 | outword(0xd0ac); //shrd ax,dx,vop |
||
8806 | |||
8807 | setzeroflag=TRUE; |
||
8808 | |||
8809 | ClearReg(DX); |
||
8810 | |||
8811 | else{ |
||
8812 | |||
8813 | op(0xB1); op(vop); /* MOV CL,num */ |
||
8814 | |||
8815 | else outword(0xEad1); // SHR AX,1 |
||
8816 | |||
8817 | warningreg(begs[1]); |
||
8818 | |||
8819 | ClearReg(AX); |
||
8820 | |||
8821 | } |
||
8822 | |||
8823 | else{ |
||
8824 | |||
8825 | op(0xB1); op(vop); /* MOV CL,num */ |
||
8826 | |||
8827 | else outword(0xE8D3); // SHR AX,CL |
||
8828 | |||
8829 | ClearReg(AX); |
||
8830 | |||
8831 | } |
||
8832 | |||
8833 | op66(razr); |
||
8834 | |||
8835 | else outword(0xE8C1); // SHR AX,num |
||
8836 | |||
8837 | ClearReg(AX); |
||
8838 | |||
8839 | setzeroflag=TRUE; |
||
8840 | |||
8841 | } |
||
8842 | |||
8843 | if(expand==FALSE)DivNum(itok.number,razr,sign); |
||
8844 | |||
8845 | divin: |
||
8846 | |||
8847 | if(!expand)ClearDX(razr,sign); |
||
8848 | |||
8849 | } |
||
8850 | |||
8851 | } |
||
8852 | |||
8853 | } |
||
8854 | |||
8855 | if(tok==tk_doublevar){ |
||
8856 | |||
8857 | tok=tk_floatvar; |
||
8858 | |||
8859 | if(tok==tk_floatvar){ |
||
8860 | |||
8861 | warningreg(regs[razr/2-1][1]); |
||
8862 | |||
8863 | tok=(razr==r16?tk_reg:tk_reg32); |
||
8864 | |||
8865 | } |
||
8866 | |||
8867 | case tk_qwordvar: |
||
8868 | |||
8869 | case tk_longvar: |
||
8870 | |||
8871 | i+=2; |
||
8872 | |||
8873 | case tk_wordvar: |
||
8874 | |||
8875 | i+=2; |
||
8876 | |||
8877 | if(expand==FALSE)ClearDX(razr,sign); |
||
8878 | |||
8879 | outseg(&itok,2); |
||
8880 | |||
8881 | if(sign)op(0x38+itok.rm); /* IDIV word ptr [#] */ |
||
8882 | |||
8883 | outaddress(&itok); |
||
8884 | |||
8885 | break; |
||
8886 | |||
8887 | if(razr==r32){ |
||
8888 | |||
8889 | getintoreg_32(i,r32,0,&ofsstr,FALSE); |
||
8890 | |||
8891 | op66(r32); |
||
8892 | |||
8893 | if(sign)op(0xF8+i); /* IDIV ECX */ |
||
8894 | |||
8895 | next=0; |
||
8896 | |||
8897 | ClearReg(AX); |
||
8898 | |||
8899 | break; |
||
8900 | |||
8901 | case tk_reg32: |
||
8902 | |||
8903 | op66(razr); |
||
8904 | |||
8905 | if(sign)op(0xF8+(unsigned int)itok.number); |
||
8906 | |||
8907 | ClearReg(AX); |
||
8908 | |||
8909 | case tk_ID: |
||
8910 | |||
8911 | case tk_proc: |
||
8912 | |||
8913 | case tk_undefproc: |
||
8914 | |||
8915 | op66(razr); |
||
8916 | |||
8917 | addESP+=razr==r16?2:4; |
||
8918 | |||
8919 | oaddstack=addstack; |
||
8920 | |||
8921 | procdo(razr==r16?(sign==0?tk_word:tk_int):(sign==0?tk_dword:tk_long)); |
||
8922 | |||
8923 | addESP-=razr==r16?2:4; |
||
8924 | |||
8925 | op(0x90+ECX); //xchg AX,CX |
||
8926 | |||
8927 | op(0x58); //pop AX |
||
8928 | |||
8929 | op66(razr); |
||
8930 | |||
8931 | if(sign)op(0xF8+ECX); /* IDIV ECX */ |
||
8932 | |||
8933 | warningreg(regs[razr/2-1][ECX]); |
||
8934 | |||
8935 | case tk_undefofs: |
||
8936 | |||
8937 | case tk_charvar: |
||
8938 | |||
8939 | case tk_bytevar: |
||
8940 | |||
8941 | case tk_postnumber: |
||
8942 | |||
8943 | defdiv: |
||
8944 | |||
8945 | if(expand==FALSE)ClearDX(razr,sign); |
||
8946 | |||
8947 | if(sign)outword(0xF9F7); /* IDIV CX */ |
||
8948 | |||
8949 | next=0; |
||
8950 | |||
8951 | ClearReg(CX); |
||
8952 | |||
8953 | break; |
||
8954 | |||
8955 | } |
||
8956 | |||
8957 | /* if(vop){ |
||
8958 | |||
8959 | if(optimizespeed)outword(0xC28B); //mov ax,dx |
||
8960 | |||
8961 | }*/ |
||
8962 | |||
8963 | if(next)nexttok(); |
||
8964 | |||
8965 | |||
8966 | |||
8967 | { |
||
8968 | |||
8969 | unsigned long num2; |
||
8970 | |||
8971 | if(razr==r16&&chip>2){ |
||
8972 | |||
8973 | if((65535/num2)!=num)goto stddiv; |
||
8974 | |||
8975 | op(0x25); |
||
8976 | |||
8977 | if(short_ok(num2,FALSE))i=2; //короткая форма |
||
8978 | |||
8979 | op(0x69+i); //imul EAX,num |
||
8980 | |||
8981 | if(i==2)op(num2); |
||
8982 | |||
8983 | op66(r32); |
||
8984 | |||
8985 | op(0x10); //shr EAX,16 |
||
8986 | |||
8987 | } |
||
8988 | |||
8989 | if(razr==r32)num=(unsigned long)0xFFFFFFFFL/num+1; |
||
8990 | |||
8991 | op66(razr); |
||
8992 | |||
8993 | if(razr==r16)outword(num); |
||
8994 | |||
8995 | op66(razr); |
||
8996 | |||
8997 | op66(razr); |
||
8998 | |||
8999 | setzeroflag=FALSE; |
||
9000 | |||
9001 | } |
||
9002 | |||
9003 | } |
||
9004 | |||
9005 | ClearDX(razr,sign); |
||
9006 | |||
9007 | } |
||
9008 | |||
9009 | void ClearDX(int razr,int sign) |
||
9010 | |||
9011 | if(sign)cwdq(razr); |
||
9012 | |||
9013 | op66(razr); |
||
9014 | |||
9015 | } |
||
9016 | |||
9017 | ClearReg(DX); |
||
9018 | |||
9019 | |||
9020 | |||
9021 | { |
||
9022 | |||
9023 | op66(razr); |
||
9024 | |||
9025 | else outword(0xF1F7); /* DIV CX */ |
||
9026 | |||
9027 | ClearReg(CX); |
||
9028 | |||
9029 | } |
||
9030 | |||
9031 | int getintoreg(int reg,int razr,int sign,char **ofsstr) |
||
9032 | |||
9033 | ITOK oitok,oitok2; |
||
9034 | |||
9035 | int oinptr,otok,otok2; |
||
9036 | |||
9037 | unsigned char ocha; |
||
9038 | |||
9039 | int operand=tk_plus; |
||
9040 | |||
9041 | char *obuf; |
||
9042 | |||
9043 | int i=0; |
||
9044 | |||
9045 | int onlynum=FALSE; |
||
9046 | |||
9047 | switch(tok){ |
||
9048 | |||
9049 | case tk_id: |
||
9050 | |||
9051 | case tk_apiproc: |
||
9052 | |||
9053 | case tk_declare: |
||
9054 | |||
9055 | default: |
||
9056 | |||
9057 | obuf=bufrm; |
||
9058 | |||
9059 | ostr=strinf; |
||
9060 | |||
9061 | oitok=itok; |
||
9062 | |||
9063 | otok=tok; |
||
9064 | |||
9065 | oline=linenum2; |
||
9066 | |||
9067 | oinput=input; |
||
9068 | |||
9069 | bmod=cur_mod; |
||
9070 | |||
9071 | bmod->freze=TRUE; |
||
9072 | |||
9073 | } |
||
9074 | |||
9075 | ocha=cha2; |
||
9076 | |||
9077 | if(tok==tk_number)onlynum=TRUE; |
||
9078 | |||
9079 | nexttok(); |
||
9080 | |||
9081 | if(itok.type==tp_opperand)operand=tok; |
||
9082 | |||
9083 | i++; |
||
9084 | |||
9085 | if(strinf.bufstr)free(strinf.bufstr); |
||
9086 | |||
9087 | case tk_div: |
||
9088 | |||
9089 | case tk_divminus: |
||
9090 | |||
9091 | if(j==0)j=1; |
||
9092 | |||
9093 | if(j==1){ |
||
9094 | |||
9095 | if(onlynum==FALSE&&caselong(itok.number)==NUMNUM)j++; |
||
9096 | |||
9097 | else{ |
||
9098 | |||
9099 | onlynum=FALSE; |
||
9100 | |||
9101 | } |
||
9102 | |||
9103 | } |
||
9104 | |||
9105 | } |
||
9106 | |||
9107 | if(bmod&&bmod->freze){ |
||
9108 | |||
9109 | while(bmod){ |
||
9110 | |||
9111 | bmod=bmod->next; |
||
9112 | |||
9113 | } |
||
9114 | |||
9115 | do{ |
||
9116 | |||
9117 | cur_mod=cur_mod->next; |
||
9118 | |||
9119 | if(temp->paramdef)free(temp->paramdef); |
||
9120 | |||
9121 | }while(bmod!=cur_mod); |
||
9122 | |||
9123 | bmod->freze=FALSE; |
||
9124 | |||
9125 | } |
||
9126 | |||
9127 | input=oinput; |
||
9128 | |||
9129 | endinptr=oendinptr; |
||
9130 | |||
9131 | itok2=oitok2; |
||
9132 | |||
9133 | tok2=otok2; |
||
9134 | |||
9135 | inptr2=oinptr; |
||
9136 | |||
9137 | endoffile=0; |
||
9138 | |||
9139 | // if(bufrm)free(bufrm); |
||
9140 | |||
9141 | bufrm=obuf; |
||
9142 | |||
9143 | break; |
||
9144 | |||
9145 | if(useeax){ |
||
9146 | |||
9147 | op(0x50); |
||
9148 | |||
9149 | do_e_axmath(0,razr,ofsstr); |
||
9150 | |||
9151 | if(optimizespeed){ |
||
9152 | |||
9153 | op(0xC0+reg); |
||
9154 | |||
9155 | else op(0x90+reg); |
||
9156 | |||
9157 | addESP-=razr==r16?2:4; |
||
9158 | |||
9159 | } |
||
9160 | |||
9161 | if(i==1&&j>=2){ |
||
9162 | |||
9163 | j=1; |
||
9164 | |||
9165 | else i=reg; |
||
9166 | |||
9167 | if(itok.type!=tp_stopper&&itok.type!=tp_compare&&tok!=tk_eof){ |
||
9168 | |||
9169 | rettype=tk_reg; |
||
9170 | |||
9171 | } |
||
9172 | |||
9173 | } |
||
9174 | |||
9175 | void dobits() |
||
9176 | |||
9177 | ITOK wtok; |
||
9178 | |||
9179 | SINFO wstr; |
||
9180 | |||
9181 | unsigned int rettype; |
||
9182 | |||
9183 | char *ofsstr=NULL; |
||
9184 | |||
9185 | razr=r32; |
||
9186 | |||
9187 | if(i<9){ |
||
9188 | |||
9189 | posiblret=rettype=tk_byte; |
||
9190 | |||
9191 | else if(i<17){ |
||
9192 | |||
9193 | razr=r16; |
||
9194 | |||
9195 | else if(i>32)razr=r64; |
||
9196 | |||
9197 | wstr=strinf; |
||
9198 | |||
9199 | wtok=itok; |
||
9200 | |||
9201 | bufrm=NULL; |
||
9202 | |||
9203 | nexttok(); |
||
9204 | |||
9205 | while(tok==tk_mult){ |
||
9206 | |||
9207 | numpointr++; |
||
9208 | |||
9209 | if(numpointr>itok.npointr)unuseableinput(); |
||
9210 | |||
9211 | MultiAssign(razr,EAX,numpointr); |
||
9212 | |||
9213 | } |
||
9214 | |||
9215 | CheckMinusNum(); |
||
9216 | |||
9217 | if(itok2.type==tp_opperand){ //сложное выражение |
||
9218 | |||
9219 | itok.flag=(unsigned char)postnumflag; |
||
9220 | |||
9221 | else{ |
||
9222 | |||
9223 | nexttok(); |
||
9224 | |||
9225 | } |
||
9226 | |||
9227 | if(razr!=r64)num2bits(&wtok,itok.number,razr); |
||
9228 | |||
9229 | int siz=wtok.bit.siz; |
||
9230 | |||
9231 | num2bits(&wtok,itok.number,r32); |
||
9232 | |||
9233 | wtok.bit.ofs=0; |
||
9234 | |||
9235 | wtok.number+=4; |
||
9236 | |||
9237 | } |
||
9238 | |||
9239 | else{ |
||
9240 | |||
9241 | if(rettype==tk_char||rettype==tk_byte)doalmath(sign,&ofsstr); |
||
9242 | |||
9243 | else if(rettype==tk_float)doeaxfloatmath(tk_reg32,AX); |
||
9244 | |||
9245 | convert_returnvalue(posiblret,rettype); |
||
9246 | |||
9247 | axtobit: |
||
9248 | |||
9249 | else{ |
||
9250 | |||
9251 | op66(r32); |
||
9252 | |||
9253 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4; |
||
9254 | |||
9255 | wtok.bit.siz=32-wtok.bit.ofs; |
||
9256 | |||
9257 | op66(r32); |
||
9258 | |||
9259 | addESP-=4; |
||
9260 | |||
9261 | outword(0xE8C1); |
||
9262 | |||
9263 | wtok.bit.siz=siz+wtok.bit.ofs-32; |
||
9264 | |||
9265 | wtok.number+=4; |
||
9266 | |||
9267 | } |
||
9268 | |||
9269 | } |
||
9270 | |||
9271 | else{ |
||
9272 | |||
9273 | wstr=strinf; |
||
9274 | |||
9275 | wtok=itok; |
||
9276 | |||
9277 | bufrm=NULL; |
||
9278 | |||
9279 | case r8: |
||
9280 | |||
9281 | break; |
||
9282 | |||
9283 | case r32: |
||
9284 | |||
9285 | break; |
||
9286 | |||
9287 | doreg_32(AX,r32); |
||
9288 | |||
9289 | } |
||
9290 | |||
9291 | } |
||
9292 | |||
9293 | } |
||
9294 | |||
9295 | void bits2reg(int reg,int razr) |
||
9296 | |||
9297 | int i,j,skip66=FALSE; |
||
9298 | |||
9299 | j=~GetBitMask(itok.bit.ofs,itok.bit.siz); |
||
9300 | |||
9301 | char *wbuf; |
||
9302 | |||
9303 | bufrm=NULL; |
||
9304 | |||
9305 | SINFO wstr; |
||
9306 | |||
9307 | strinf.bufstr=NULL; |
||
9308 | |||
9309 | case r8: |
||
9310 | |||
9311 | getintoal(tk_bytevar,&wtok,wbuf,&wstr); |
||
9312 | |||
9313 | op(4+0x20); //and al,j |
||
9314 | |||
9315 | } |
||
9316 | |||
9317 | else{ |
||
9318 | |||
9319 | outseg(&itok,2); |
||
9320 | |||
9321 | op(reg*8+itok.rm); |
||
9322 | |||
9323 | if(i!=8){ |
||
9324 | |||
9325 | op(128+64+reg+0x20); |
||
9326 | |||
9327 | } |
||
9328 | |||
9329 | if(itok.bit.ofs){ //shr al,ofs |
||
9330 | |||
9331 | op(0xD0); |
||
9332 | |||
9333 | } |
||
9334 | |||
9335 | op(0xC0); |
||
9336 | |||
9337 | op(itok.bit.ofs); |
||
9338 | |||
9339 | } |
||
9340 | |||
9341 | case r16: |
||
9342 | |||
9343 | if(reg==AX){ |
||
9344 | |||
9345 | if(razr==r16&&i!=16){ |
||
9346 | |||
9347 | op(4+1+0x20); |
||
9348 | |||
9349 | } |
||
9350 | |||
9351 | op66(razr); //and (e)ax,j |
||
9352 | |||
9353 | op(128+2+1); |
||
9354 | |||
9355 | op((int)j); |
||
9356 | |||
9357 | else{ |
||
9358 | |||
9359 | outdword(j); |
||
9360 | |||
9361 | } |
||
9362 | |||
9363 | if(itok.bit.ofs){ //shr (e)ax,ofs |
||
9364 | |||
9365 | if(itok.bit.ofs==1)outword(0xE8D1); |
||
9366 | |||
9367 | outword(0xE8C1); |
||
9368 | |||
9369 | } |
||
9370 | |||
9371 | } |
||
9372 | |||
9373 | int reg1=idxregs[0],reg2=idxregs[1]; |
||
9374 | |||
9375 | if(reg==idxregs[2]||reg==idxregs[1]){ |
||
9376 | |||
9377 | if(reg==idxregs[1])reg2=idxregs[0]; |
||
9378 | |||
9379 | } |
||
9380 | |||
9381 | reg1=reg; |
||
9382 | |||
9383 | } |
||
9384 | |||
9385 | op66(razr); |
||
9386 | |||
9387 | op(0x8B); |
||
9388 | |||
9389 | outaddress(&itok); |
||
9390 | |||
9391 | op66(razr); //and reg,j |
||
9392 | |||
9393 | op(128+2+1); |
||
9394 | |||
9395 | op(j); |
||
9396 | |||
9397 | else{ |
||
9398 | |||
9399 | op(128+64+reg+0x20); |
||
9400 | |||
9401 | else outdword(j); |
||
9402 | |||
9403 | } |
||
9404 | |||
9405 | op66(razr); |
||
9406 | |||
9407 | op(0xD1); |
||
9408 | |||
9409 | } |
||
9410 | |||
9411 | op(0xC1); |
||
9412 | |||
9413 | op(itok.bit.ofs); |
||
9414 | |||
9415 | } |
||
9416 | |||
9417 | break; |
||
9418 | |||
9419 | if(reg==AX){ |
||
9420 | |||
9421 | itok.number+=4; |
||
9422 | |||
9423 | op(0x8B); |
||
9424 | |||
9425 | outaddress(&itok); |
||
9426 | |||
9427 | op(128); |
||
9428 | |||
9429 | op(li[itok.bit.siz+itok.bit.ofs-32]-1); |
||
9430 | |||
9431 | op66(r32); |
||
9432 | |||
9433 | op(0xC2); |
||
9434 | |||
9435 | itok.number-=4; |
||
9436 | |||
9437 | } |
||
9438 | |||
9439 | int reg1=DX; |
||
9440 | |||
9441 | CheckAllMassiv(bufrm,4,&strinf,&itok); |
||
9442 | |||
9443 | outseg(&itok,2); |
||
9444 | |||
9445 | op(reg*8+itok.rm); |
||
9446 | |||
9447 | itok.number+=4; |
||
9448 | |||
9449 | op(0x8B); |
||
9450 | |||
9451 | outaddress(&itok); |
||
9452 | |||
9453 | op(128+(reg1<4?0:3)); |
||
9454 | |||
9455 | op(li[itok.bit.siz+itok.bit.ofs-32]-1); |
||
9456 | |||
9457 | itok.number-=4; |
||
9458 | |||
9459 | outword(0xAC0F); //shrd edx,eax,ofs |
||
9460 | |||
9461 | op(itok.bit.ofs); |
||
9462 | |||
9463 | } |
||
9464 | |||
9465 | break; |
||
9466 | |||
9467 | ClearReg(AX); |
||
9468 | |||
9469 | } |
||
9470 | |||
9471 | void num2bits(ITOK *gtok,unsigned long num,int razr) |
||
9472 | |||
9473 | unsigned int j,mask; |
||
9474 | |||
9475 | j=li[gtok->bit.siz]-1; |
||
9476 | |||
9477 | if(razr!=r8){ |
||
9478 | |||
9479 | outseg(gtok,2); |
||
9480 | |||
9481 | op(128+2+1); |
||
9482 | |||
9483 | outaddress(gtok); |
||
9484 | |||
9485 | } |
||
9486 | |||
9487 | op(128+1); |
||
9488 | |||
9489 | outaddress(gtok); |
||
9490 | |||
9491 | if(razr==r16)outword(mask); |
||
9492 | |||
9493 | } |
||
9494 | |||
9495 | else{ |
||
9496 | |||
9497 | op(128); |
||
9498 | |||
9499 | outaddress(gtok); |
||
9500 | |||
9501 | } |
||
9502 | |||
9503 | num=(num&j)< |
||
9504 | |||
9505 | if(num<256&&razr==r16)razr=r8; |
||
9506 | |||
9507 | op66(razr); |
||
9508 | |||
9509 | if((postnumflag&f_reloc)==0&&short_ok(num,razr/2-1)){ |
||
9510 | |||
9511 | op(gtok->rm+8); |
||
9512 | |||
9513 | op(num); |
||
9514 | |||
9515 | else{ |
||
9516 | |||
9517 | op(gtok->rm+8); |
||
9518 | |||
9519 | if((postnumflag&f_reloc)!=0)AddReloc(); |
||
9520 | |||
9521 | else outdword(num); |
||
9522 | |||
9523 | } |
||
9524 | |||
9525 | if((unsigned char)num!=0){ |
||
9526 | |||
9527 | op(128); |
||
9528 | |||
9529 | outaddress(gtok); |
||
9530 | |||
9531 | } |
||
9532 | |||
9533 | } |
||
9534 | |||
9535 | void reg2bits(ITOK *gtok,int razr) |
||
9536 | |||
9537 | int i,j,mask; |
||
9538 | |||
9539 | mask=GetBitMask(gtok->bit.ofs,gtok->bit.siz); |
||
9540 | |||
9541 | switch(razr){ |
||
9542 | |||
9543 | if(i!=8){ |
||
9544 | |||
9545 | op(j); |
||
9546 | |||
9547 | outseg(gtok,2); //and bits,mask |
||
9548 | |||
9549 | op(gtok->rm+0x20); |
||
9550 | |||
9551 | op(mask); |
||
9552 | |||
9553 | outseg(gtok,2); |
||
9554 | |||
9555 | op(gtok->rm); |
||
9556 | |||
9557 | break; |
||
9558 | |||
9559 | case r32: |
||
9560 | |||
9561 | op66(razr); //and (e)ax,size |
||
9562 | |||
9563 | outword(j); |
||
9564 | |||
9565 | else if(razr==r32&&i!=32){ |
||
9566 | |||
9567 | if(short_ok(j,TRUE)){ |
||
9568 | |||
9569 | op(128+64+0x20); |
||
9570 | |||
9571 | } |
||
9572 | |||
9573 | op(4+1+0x20); |
||
9574 | |||
9575 | } |
||
9576 | |||
9577 | op66(razr); //and bits,mask |
||
9578 | |||
9579 | if(short_ok(mask,razr/2-1)){ |
||
9580 | |||
9581 | op(gtok->rm+0x20); |
||
9582 | |||
9583 | op(mask); |
||
9584 | |||
9585 | else{ |
||
9586 | |||
9587 | op(gtok->rm+0x20); |
||
9588 | |||
9589 | if(razr==r16)outword(mask); |
||
9590 | |||
9591 | } |
||
9592 | |||
9593 | op66(razr); |
||
9594 | |||
9595 | op(1+8); |
||
9596 | |||
9597 | outaddress(gtok); |
||
9598 | |||
9599 | } |
||
9600 | |||
9601 | |||
9602 | |||
9603 | { |
||
9604 | |||
9605 | nexttok(); |
||
9606 | |||
9607 | nexttok(); |
||
9608 | |||
9609 | } |
||
9610 | |||
9611 | unuseableinput(); |
||
9612 | |||
9613 | if(tok==tk_pointer){ |
||
9614 | |||
9615 | } |
||
9616 | |||
9617 | } |
||
9618 | |||
9619 | void cpointr(int reg,int numpointr) |
||
9620 | |||
9621 | if(itok.type==tk_proc){ |
||
9622 | |||
9623 | tok=tk_proc; |
||
9624 | |||
9625 | else{ |
||
9626 | |||
9627 | if(am32){ |
||
9628 | |||
9629 | |||
9630 | |||
9631 | else{ |
||
9632 | |||
9633 | |||
9634 | |||
9635 | compressoffset(&itok); |
||
9636 | |||
9637 | return; |
||
9638 | |||
9639 | int razr=typesize(itok.type); |
||
9640 | |||
9641 | getpointeradr(&itok,bufrm,&strinf,numpointr-1,razr,reg); |
||
9642 | |||
9643 | else tok=(am32==FALSE?tk_wordvar:tk_dwordvar); |
||
9644 | |||
9645 | else if(numpointr |
||
9646 | |||
9647 | tok=(am32==FALSE?tk_wordvar:tk_dwordvar); |
||
9648 | |||
9649 | else unuseableinput(); |
||
9650 | |||
9651 | |||
9652 | |||
9653 | { |
||
9654 | |||
9655 | wtok->rm=wtok->sib; |
||
9656 | |||
9657 | wtok->sib=CODE32; |
||
9658 | |||
9659 | } |
||
9660 | |||
9661 | wtok->sib=CODE16; |
||
9662 | |||
9663 | } |
||
9664 | |||
9665 | } |
||
9666 | |||
9667 | int razr=typesize(wtok->type); |
||
9668 | |||
9669 | if(reg==ureg)reg=idxregs[1]; |
||
9670 | |||
9671 | getpointeradr(wtok,wbuf,wstr,npointr-1,razr,reg); |
||
9672 | |||
9673 | else *otok=(am32==FALSE?tk_wordvar:tk_dwordvar); |
||
9674 | |||
9675 | else if(npointr |
||
9676 | |||
9677 | if(npointr)getpointeradr(wtok,wbuf,wstr,npointr-1,razr,reg); |
||
9678 | |||
9679 | } |
||
9680 | |||
9681 | memcpy(wtok,&itok,sizeof(ITOK)); |
||
9682 | |||
9683 | } |
||
9684 | |||
9685 | int CheckAddOnly() |
||
9686 | |||
9687 | ITOK oitok,oitok2; |
||
9688 | |||
9689 | int oinptr,otok,otok2; |
||
9690 | |||
9691 | char *obuf; |
||
9692 | |||
9693 | int retval=TRUE; |
||
9694 | |||
9695 | int changesign=0; |
||
9696 | |||
9697 | else if(tok!=tk_plusequals)return FALSE; |
||
9698 | |||
9699 | newloop: |
||
9700 | |||
9701 | bufrm=NULL; |
||
9702 | |||
9703 | strinf.bufstr=NULL; |
||
9704 | |||
9705 | oitok2=itok2; |
||
9706 | |||
9707 | otok2=tok2; |
||
9708 | |||
9709 | oinptr=inptr2; |
||
9710 | |||
9711 | while(tok2==tk_minus||tok2==tk_mult)nexttok(); |
||
9712 | |||
9713 | nexttok(); |
||
9714 | |||
9715 | case tk_ID: |
||
9716 | |||
9717 | case tk_proc: |
||
9718 | |||
9719 | case tk_undefproc: |
||
9720 | |||
9721 | retval=FALSE; |
||
9722 | |||
9723 | break; |
||
9724 | |||
9725 | if(itok.type==tp_stopper)break; |
||
9726 | |||
9727 | if(tok!=tk_plus&&tok!=tk_minus){ |
||
9728 | |||
9729 | break; |
||
9730 | |||
9731 | else if(changesign==2){ |
||
9732 | |||
9733 | char c; |
||
9734 | |||
9735 | i--; |
||
9736 | |||
9737 | i--; |
||
9738 | |||
9739 | i++; |
||
9740 | |||
9741 | else c='-'; |
||
9742 | |||
9743 | } |
||
9744 | |||
9745 | } |
||
9746 | |||
9747 | if(tok!=tk_number&&tok!=tk_postnumber&&tok!=tk_undefofs){ |
||
9748 | |||
9749 | if(bufrm)free(bufrm); |
||
9750 | |||
9751 | } |
||
9752 | |||
9753 | } |
||
9754 | |||
9755 | itok=oitok; |
||
9756 | |||
9757 | tok=otok; |
||
9758 | |||
9759 | linenum2=oline; |
||
9760 | |||
9761 | cha2=ocha; |
||
9762 | |||
9763 | bufrm=obuf; |
||
9764 | |||
9765 | if(j==1)retval=FALSE; |
||
9766 | |||
9767 | changesign++; |
||
9768 | |||
9769 | } |
||
9770 | |||
9771 | } |
||
9772 | |||
9773 | int doqwordvar(int terminater) //64 bit memory variable |
||
9774 | |||
9775 | unsigned char next=1,getfromAX=0; |
||
9776 | |||
9777 | int sign,i; |
||
9778 | |||
9779 | char *wbuf,*rbuf; |
||
9780 | |||
9781 | int retrez=0,pointr=0; |
||
9782 | |||
9783 | int reg; |
||
9784 | |||
9785 | int reg1=idxregs[0],reg2=idxregs[1]; |
||
9786 | |||
9787 | sign=0; |
||
9788 | |||
9789 | strinf.bufstr=NULL; |
||
9790 | |||
9791 | wbuf=bufrm; |
||
9792 | |||
9793 | otok=tok; |
||
9794 | |||
9795 | switch(tok){ |
||
9796 | |||
9797 | nexttok(); |
||
9798 | |||
9799 | while(tok==tk_mult){ |
||
9800 | |||
9801 | numpointr++; |
||
9802 | |||
9803 | if(numpointr>itok.npointr){ |
||
9804 | |||
9805 | } |
||
9806 | |||
9807 | if(itok2.type==tp_opperand){ //сложное выражение |
||
9808 | |||
9809 | switch(rettype){ |
||
9810 | |||
9811 | case tk_double: sign=3; break; |
||
9812 | |||
9813 | } |
||
9814 | |||
9815 | next=0; |
||
9816 | |||
9817 | goto numbertovar; |
||
9818 | |||
9819 | } |
||
9820 | |||
9821 | } |
||
9822 | |||
9823 | switch(tok){ |
||
9824 | |||
9825 | if((itok.flag&f_reloc)==0){ |
||
9826 | |||
9827 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
9828 | |||
9829 | op66(r32); |
||
9830 | |||
9831 | op(0x83); |
||
9832 | |||
9833 | outaddress(&wtok); |
||
9834 | |||
9835 | if(i==1)break; |
||
9836 | |||
9837 | compressoffset(&wtok); |
||
9838 | |||
9839 | break; |
||
9840 | |||
9841 | if(itok.lnumber==0xFFFFFFFFFFFFFFFFLL){ |
||
9842 | |||
9843 | for(i=0;i<2;i++){ |
||
9844 | |||
9845 | outseg(&wtok,2); |
||
9846 | |||
9847 | op(wtok.rm+0x8); |
||
9848 | |||
9849 | op(0xFF); |
||
9850 | |||
9851 | wtok.number+=4; |
||
9852 | |||
9853 | } |
||
9854 | |||
9855 | } |
||
9856 | |||
9857 | numbertovar: |
||
9858 | |||
9859 | for(i=0;i<2;i++){ |
||
9860 | |||
9861 | if(regoverstack&&short_ok(itok.number,TRUE)&&(itok.flag&f_reloc)==0){ |
||
9862 | |||
9863 | op(itok.number); //push short number |
||
9864 | |||
9865 | outseg(&wtok,2); |
||
9866 | |||
9867 | op(wtok.rm); |
||
9868 | |||
9869 | } |
||
9870 | |||
9871 | outseg(&wtok,2); |
||
9872 | |||
9873 | op(wtok.rm); |
||
9874 | |||
9875 | if((itok.flag&f_reloc)!=0)AddReloc(); |
||
9876 | |||
9877 | } |
||
9878 | |||
9879 | itok.lnumber>>=32; |
||
9880 | |||
9881 | compressoffset(&wtok); |
||
9882 | |||
9883 | break; |
||
9884 | |||
9885 | case tk_postnumber: |
||
9886 | |||
9887 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
9888 | |||
9889 | outseg(&wtok,2); |
||
9890 | |||
9891 | op(wtok.rm); |
||
9892 | |||
9893 | if(tok==tk_apioffset)AddApiToPost(itok.number); |
||
9894 | |||
9895 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
9896 | |||
9897 | // else if((itok.flag&f_reloc)!=0)AddReloc(); |
||
9898 | |||
9899 | } |
||
9900 | |||
9901 | compressoffset(&wtok); |
||
9902 | |||
9903 | outseg(&wtok,2); |
||
9904 | |||
9905 | op(wtok.rm+0x20); |
||
9906 | |||
9907 | op(0); |
||
9908 | |||
9909 | case tk_reg64: |
||
9910 | |||
9911 | case tk_reg32: |
||
9912 | |||
9913 | ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| |
||
9914 | |||
9915 | op66(r32); |
||
9916 | |||
9917 | op(0xA3); // MOV [word],AX |
||
9918 | |||
9919 | AddUndefOff(2,wtok.name); |
||
9920 | |||
9921 | } |
||
9922 | |||
9923 | else outdword(wtok.number); |
||
9924 | |||
9925 | else{ |
||
9926 | |||
9927 | op66(r32); |
||
9928 | |||
9929 | op(0x89); |
||
9930 | |||
9931 | outaddress(&wtok); |
||
9932 | |||
9933 | wtok.number+=4; |
||
9934 | |||
9935 | op66(r32); |
||
9936 | |||
9937 | op(0x83); |
||
9938 | |||
9939 | outaddress(&wtok); |
||
9940 | |||
9941 | break; |
||
9942 | |||
9943 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
9944 | |||
9945 | outseg(&wtok,2); |
||
9946 | |||
9947 | op(wtok.rm); |
||
9948 | |||
9949 | outdword(addpoststring()); |
||
9950 | |||
9951 | compressoffset(&wtok); |
||
9952 | |||
9953 | outseg(&wtok,2); |
||
9954 | |||
9955 | op(wtok.rm+0x20); |
||
9956 | |||
9957 | op(0); |
||
9958 | |||
9959 | default: |
||
9960 | |||
9961 | reg=EAX|(EDX*256); |
||
9962 | |||
9963 | doregmath64(reg); |
||
9964 | |||
9965 | next=0; |
||
9966 | |||
9967 | } |
||
9968 | |||
9969 | if(getfromAX){ |
||
9970 | |||
9971 | itok.number=EAX|(EDX*256); |
||
9972 | |||
9973 | reg=itok.number&255; |
||
9974 | |||
9975 | if(reg==AX&&wbuf==NULL&&wstr.bufstr==NULL&& |
||
9976 | |||
9977 | (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
9978 | |||
9979 | outseg(&wtok,1); |
||
9980 | |||
9981 | if(wtok.post==UNDEF_OFSET){ |
||
9982 | |||
9983 | wtok.post=0; |
||
9984 | |||
9985 | if(am32==FALSE)outword(wtok.number); |
||
9986 | |||
9987 | } |
||
9988 | |||
9989 | CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); |
||
9990 | |||
9991 | outseg(&wtok,2); |
||
9992 | |||
9993 | op((unsigned int)reg*8+wtok.rm); |
||
9994 | |||
9995 | } |
||
9996 | |||
9997 | wtok.number+=4; |
||
9998 | |||
9999 | reg=itok.number/256; |
||
10000 | |||
10001 | warningreg(regs[1][EAX]); |
||
10002 | |||
10003 | ClearReg(AX); |
||
10004 | |||
10005 | retrez=tk_reg64; |
||
10006 | |||
10007 | break; |
||
10008 | |||
10009 | case tk_plusplus: |
||
10010 | |||
10011 | op66(r32); |
||
10012 | |||
10013 | incdec: |
||
10014 | |||
10015 | outaddress(&wtok); |
||
10016 | |||
10017 | compressoffset(&wtok); |
||
10018 | |||
10019 | op66(r32); |
||
10020 | |||
10021 | op(0x83); op(0x10+vop+wtok.rm); |
||
10022 | |||
10023 | op(0); |
||
10024 | |||
10025 | case tk_xorequals: vop+=0x08; |
||
10026 | |||
10027 | case tk_andequals: vop+=0x18; |
||
10028 | |||
10029 | case tk_plusequals: |
||
10030 | |||
10031 | if(itok2.type==tp_opperand){ |
||
10032 | |||
10033 | if(OnlyNumber(4)){ |
||
10034 | |||
10035 | otok=tok; |
||
10036 | |||
10037 | goto num; |
||
10038 | |||
10039 | } |
||
10040 | |||
10041 | } |
||
10042 | |||
10043 | switch(tok){ |
||
10044 | |||
10045 | case tk_postnumber: |
||
10046 | |||
10047 | case tk_apioffset: |
||
10048 | |||
10049 | for(i=0;i<2;i++){ |
||
10050 | |||
10051 | op66(r32); |
||
10052 | |||
10053 | if(tok==tk_number&&(itok.flag&f_reloc)==0&&(vop==0||vop==0x28)){ |
||
10054 | |||
10055 | if(vop)vop=8; |
||
10056 | |||
10057 | goto incdec; |
||
10058 | |||
10059 | if(itok.number==1){ |
||
10060 | |||
10061 | outaddress(&wtok); |
||
10062 | |||
10063 | } |
||
10064 | |||
10065 | if(i==1){ |
||
10066 | |||
10067 | else if(vop==0x28)vop-=0x10; |
||
10068 | |||
10069 | if(tok!=tk_apioffset&&tok!=tk_undefofs&&tok!=tk_postnumber&&(itok.flag&f_reloc)==0&& |
||
10070 | |||
10071 | op(0x83); |
||
10072 | |||
10073 | outaddress(&wtok); |
||
10074 | |||
10075 | } |
||
10076 | |||
10077 | op(0x81); |
||
10078 | |||
10079 | outaddress(&wtok); |
||
10080 | |||
10081 | else{ |
||
10082 | |||
10083 | else if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
10084 | |||
10085 | outdword(itok.number); |
||
10086 | |||
10087 | } |
||
10088 | |||
10089 | wtok.number+=4; |
||
10090 | |||
10091 | itok.lnumber>>=32; |
||
10092 | |||
10093 | if(next==0)tok=otok; |
||
10094 | |||
10095 | case tk_reg64: |
||
10096 | |||
10097 | for(i=0;i<2;i++){ |
||
10098 | |||
10099 | if(vop==0)vop+=0x10; |
||
10100 | |||
10101 | } |
||
10102 | |||
10103 | op66(r32); |
||
10104 | |||
10105 | op(0x01+vop); op((unsigned int)reg*8+wtok.rm); |
||
10106 | |||
10107 | if(i==1)break; |
||
10108 | |||
10109 | compressoffset(&wtok); |
||
10110 | |||
10111 | } |
||
10112 | |||
10113 | default: |
||
10114 | |||
10115 | reg=EAX|(EDX*256); |
||
10116 | |||
10117 | doregmath64(reg); |
||
10118 | |||
10119 | reg=EAX; |
||
10120 | |||
10121 | op66(r32); |
||
10122 | |||
10123 | op(wtok.rm+reg*8); |
||
10124 | |||
10125 | if(i==1)break; |
||
10126 | |||
10127 | if(vop==0x28)vop=0x18; |
||
10128 | |||
10129 | wtok.number+=4; |
||
10130 | |||
10131 | } |
||
10132 | |||
10133 | retrez=tk_reg64; |
||
10134 | |||
10135 | warningreg(regs[1][EDX]); |
||
10136 | |||
10137 | } |
||
10138 | |||
10139 | break; |
||
10140 | |||
10141 | getoperand(am32==TRUE?EAX:BX); |
||
10142 | |||
10143 | if(itok.lnumber==1)break; |
||
10144 | |||
10145 | ZeroReg(EAX,r32); |
||
10146 | |||
10147 | goto getfromax; |
||
10148 | |||
10149 | if((i=caselong(itok.number))!=NUMNUM){ |
||
10150 | |||
10151 | ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| |
||
10152 | |||
10153 | op66(r32); |
||
10154 | |||
10155 | op(0xA1); // MOV EAX,[dword] |
||
10156 | |||
10157 | AddUndefOff(2,wtok.name); |
||
10158 | |||
10159 | } |
||
10160 | |||
10161 | else outdword(wtok.number); |
||
10162 | |||
10163 | else{ |
||
10164 | |||
10165 | op66(r32); |
||
10166 | |||
10167 | op(0x8B); |
||
10168 | |||
10169 | outaddress(&wtok); |
||
10170 | |||
10171 | wtok.number+=4; |
||
10172 | |||
10173 | ClearReg(AX); |
||
10174 | |||
10175 | op66(r32); |
||
10176 | |||
10177 | op(0x0F); |
||
10178 | |||
10179 | op(wtok.rm); // SHLD [rmword],CL |
||
10180 | |||
10181 | op(i); |
||
10182 | |||
10183 | compressoffset(&wtok); |
||
10184 | |||
10185 | op66(r32); |
||
10186 | |||
10187 | op(0xC1); |
||
10188 | |||
10189 | outaddress(&wtok); |
||
10190 | |||
10191 | break; |
||
10192 | |||
10193 | } |
||
10194 | |||
10195 | wtok.number+=4; |
||
10196 | |||
10197 | for(i=0;i<2;i++){ |
||
10198 | |||
10199 | outseg(&wtok,2); |
||
10200 | |||
10201 | outaddress(&wtok); |
||
10202 | |||
10203 | wtok.number-=4; |
||
10204 | |||
10205 | } |
||
10206 | |||
10207 | getintoreg64(reg); |
||
10208 | |||
10209 | CallExternProc("__llmul"); |
||
10210 | |||
10211 | goto getfromax; |
||
10212 | |||
10213 | getoperand(am32==TRUE?EAX:BX); |
||
10214 | |||
10215 | if(itok.number==0){ |
||
10216 | |||
10217 | break; |
||
10218 | |||
10219 | if(itok.number==1)break; |
||
10220 | |||
10221 | wtok.number+=4; |
||
10222 | |||
10223 | if(wbuf==NULL&&wstr.bufstr==NULL&& |
||
10224 | |||
10225 | (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
10226 | |||
10227 | outseg(&wtok,1); |
||
10228 | |||
10229 | if(wtok.post==UNDEF_OFSET){ |
||
10230 | |||
10231 | wtok.post=0; |
||
10232 | |||
10233 | if(am32==FALSE)outword(wtok.number); |
||
10234 | |||
10235 | } |
||
10236 | |||
10237 | CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); |
||
10238 | |||
10239 | outseg(&wtok,2); |
||
10240 | |||
10241 | op(wtok.rm); |
||
10242 | |||
10243 | } |
||
10244 | |||
10245 | compressoffset(&wtok); |
||
10246 | |||
10247 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10248 | |||
10249 | outseg(&wtok,3); |
||
10250 | |||
10251 | op(0xAC); |
||
10252 | |||
10253 | outaddress(&wtok); |
||
10254 | |||
10255 | wtok.number+=4; |
||
10256 | |||
10257 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10258 | |||
10259 | outseg(&wtok,2); |
||
10260 | |||
10261 | op(0x28+wtok.rm); |
||
10262 | |||
10263 | op(i); |
||
10264 | |||
10265 | } |
||
10266 | |||
10267 | number=itok.lnumber>>32; |
||
10268 | |||
10269 | op66(r32); |
||
10270 | |||
10271 | op(0x6A); |
||
10272 | |||
10273 | } |
||
10274 | |||
10275 | op(0x68); |
||
10276 | |||
10277 | outdword(number); |
||
10278 | |||
10279 | if(i==1)break; |
||
10280 | |||
10281 | } |
||
10282 | |||
10283 | } |
||
10284 | |||
10285 | getintoreg64(reg); |
||
10286 | |||
10287 | op66(r32); |
||
10288 | |||
10289 | op66(r32); |
||
10290 | |||
10291 | next=0; |
||
10292 | |||
10293 | addESP+=8; |
||
10294 | |||
10295 | reg=EAX; |
||
10296 | |||
10297 | if(reg==AX&&wbuf==NULL&&wstr.bufstr==NULL&& |
||
10298 | |||
10299 | (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
10300 | |||
10301 | outseg(&wtok,1); |
||
10302 | |||
10303 | if(wtok.post==UNDEF_OFSET){ |
||
10304 | |||
10305 | } |
||
10306 | |||
10307 | else outdword(wtok.number); |
||
10308 | |||
10309 | else{ |
||
10310 | |||
10311 | op66(r32); |
||
10312 | |||
10313 | op(0x8B); |
||
10314 | |||
10315 | outaddress(&wtok); |
||
10316 | |||
10317 | if(i==1)break; |
||
10318 | |||
10319 | compressoffset(&wtok); |
||
10320 | |||
10321 | } |
||
10322 | |||
10323 | addESP-=8; |
||
10324 | |||
10325 | compressoffset(&wtok); |
||
10326 | |||
10327 | case tk_swap: |
||
10328 | |||
10329 | regdi=TRUE; |
||
10330 | |||
10331 | rbuf=bufrm; |
||
10332 | |||
10333 | if(am32!=FALSE&&wbuf!=NULL&&wstr.bufstr!=NULL)regdi=FALSE; |
||
10334 | |||
10335 | case tk_reg64: |
||
10336 | |||
10337 | reg=itok.number&255; |
||
10338 | |||
10339 | op66(r32); |
||
10340 | |||
10341 | op(0x87); |
||
10342 | |||
10343 | outaddress(&wtok); |
||
10344 | |||
10345 | if(i==1)break; |
||
10346 | |||
10347 | wtok.number+=4; |
||
10348 | |||
10349 | } |
||
10350 | |||
10351 | case tk_qwordvar: |
||
10352 | |||
10353 | getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32,TRUE); |
||
10354 | |||
10355 | op66(r32); |
||
10356 | |||
10357 | op(0x87); // XCHG AX,[wloc] |
||
10358 | |||
10359 | outaddress(&itok); |
||
10360 | |||
10361 | if(wbuf==NULL&&wstr.bufstr==NULL&& |
||
10362 | |||
10363 | (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
10364 | |||
10365 | outseg(&wtok,1); |
||
10366 | |||
10367 | if(wtok.post==UNDEF_OFSET){ |
||
10368 | |||
10369 | wtok.post=0; |
||
10370 | |||
10371 | if(am32==FALSE)outword(wtok.number); //???? |
||
10372 | |||
10373 | } |
||
10374 | |||
10375 | CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); |
||
10376 | |||
10377 | outseg(&wtok,2); |
||
10378 | |||
10379 | outaddress(&wtok); |
||
10380 | |||
10381 | if(i==1)break; |
||
10382 | |||
10383 | compressoffset(&itok); |
||
10384 | |||
10385 | compressoffset(&wtok); |
||
10386 | |||
10387 | warningreg(regs[1][EAX]); |
||
10388 | |||
10389 | break; |
||
10390 | |||
10391 | } |
||
10392 | |||
10393 | case tk_rrequals: |
||
10394 | |||
10395 | wtok.number+=4; |
||
10396 | |||
10397 | case tk_llequals: |
||
10398 | |||
10399 | if(itok2.type!=tp_stopper){ |
||
10400 | |||
10401 | ClearReg(CX); |
||
10402 | |||
10403 | next=0; |
||
10404 | |||
10405 | } |
||
10406 | |||
10407 | i=0; |
||
10408 | |||
10409 | else{ |
||
10410 | |||
10411 | getintobeg(CL,&ofsstr); |
||
10412 | |||
10413 | warningreg(begs[1]); |
||
10414 | |||
10415 | } |
||
10416 | |||
10417 | } |
||
10418 | |||
10419 | ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| |
||
10420 | |||
10421 | op66(r32); |
||
10422 | |||
10423 | op(0xA1); // MOV EAX,[dword] |
||
10424 | |||
10425 | AddUndefOff(2,wtok.name); |
||
10426 | |||
10427 | } |
||
10428 | |||
10429 | else outdword(wtok.number); |
||
10430 | |||
10431 | else{ |
||
10432 | |||
10433 | op66(r32); |
||
10434 | |||
10435 | op(0x8B); |
||
10436 | |||
10437 | outaddress(&wtok); |
||
10438 | |||
10439 | if(vop)wtok.number-=4; |
||
10440 | |||
10441 | compressoffset(&wtok); |
||
10442 | |||
10443 | warningreg(regs[1][EAX]); |
||
10444 | |||
10445 | op66(r32); |
||
10446 | |||
10447 | op(0x0F); |
||
10448 | |||
10449 | op(wtok.rm); // SHLD [rmword],CL |
||
10450 | |||
10451 | if(i==0)op((unsigned int)itok.number); |
||
10452 | |||
10453 | else wtok.number-=4; |
||
10454 | |||
10455 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10456 | |||
10457 | outseg(&wtok,2); |
||
10458 | |||
10459 | op(0x20+vop+wtok.rm); |
||
10460 | |||
10461 | if(i==0)op(itok.number); |
||
10462 | |||
10463 | default: operatorexpected(); break; |
||
10464 | |||
10465 | KillVar(wtok.name); |
||
10466 | |||
10467 | if(terminater==tk_semicolon)seminext(); |
||
10468 | |||
10469 | return retrez; |
||
10470 | |||
10471 | |||
10472 | |||
10473 | { |
||
10474 | |||
10475 | *reg2=idxregs[1]; |
||
10476 | |||
10477 | if(r2==idxregs[1]){ |
||
10478 | |||
10479 | *reg2=idxregs[3]; |
||
10480 | |||
10481 | else{ |
||
10482 | |||
10483 | if(r2==idxregs[2])*reg2=idxregs[3]; |
||
10484 | |||
10485 | } |
||
10486 | |||
10487 | if(r1==idxregs[1]){ |
||
10488 | |||
10489 | *reg1=idxregs[2]; |
||
10490 | |||
10491 | } |
||
10492 | |||
10493 | *reg1=idxregs[0]; |
||
10494 | |||
10495 | else *reg2=idxregs[2]; |
||
10496 | |||
10497 | } |
||
10498 | |||
10499 | |||
10500 | |||
10501 | { |
||
10502 | |||
10503 | int vop=0,sign=0; |
||
10504 | |||
10505 | int reg1,reg2; |
||
10506 | |||
10507 | int r1,r2; |
||
10508 | |||
10509 | int rettype; |
||
10510 | |||
10511 | int numpointr=0; |
||
10512 | |||
10513 | r1=reg&255; |
||
10514 | |||
10515 | Select2FreeReg(r1,r2,®1,®2); |
||
10516 | |||
10517 | nexttok(); |
||
10518 | |||
10519 | case tk_assign://= |
||
10520 | |||
10521 | /*-----------------31.08.05 18:39------------------- |
||
10522 | |||
10523 | --------------------------------------------------*/ |
||
10524 | |||
10525 | while(tok==tk_mult){ |
||
10526 | |||
10527 | numpointr++; |
||
10528 | |||
10529 | if(numpointr>itok.npointr){ |
||
10530 | |||
10531 | } |
||
10532 | |||
10533 | if(tok==tk_number){ //проверка и суммирование чисел |
||
10534 | |||
10535 | case tk_float: sign=2; break; |
||
10536 | |||
10537 | case tk_qword: sign=4; break; |
||
10538 | |||
10539 | if(OnlyNumber(sign)){ |
||
10540 | |||
10541 | MovRegNum(r32,0,itok.lnumber>>32,r2); |
||
10542 | |||
10543 | break; |
||
10544 | |||
10545 | } |
||
10546 | |||
10547 | doeaxfloatmath(tk_stackstart,0,rettype==tk_float?0:4); |
||
10548 | |||
10549 | op(0x58+r1); |
||
10550 | |||
10551 | if(rettype==tk_float){ |
||
10552 | |||
10553 | } |
||
10554 | |||
10555 | next=0; |
||
10556 | |||
10557 | } |
||
10558 | |||
10559 | |||
10560 | |||
10561 | getintoreg64(reg); |
||
10562 | |||
10563 | next=0; |
||
10564 | |||
10565 | case tk_plusplus: op66(r32); op(0x40+r1); |
||
10566 | |||
10567 | op(0x83); |
||
10568 | |||
10569 | op(0); |
||
10570 | |||
10571 | case tk_minusminus: op66(r32); op(0x48+r1); |
||
10572 | |||
10573 | op(0x83); |
||
10574 | |||
10575 | op(0); |
||
10576 | |||
10577 | case tk_swap: |
||
10578 | |||
10579 | switch(tok){ |
||
10580 | |||
10581 | reg=r1; |
||
10582 | |||
10583 | CheckAllMassiv(bufrm,8,&strinf,&itok,reg1,reg2); |
||
10584 | |||
10585 | outseg(&itok,2); |
||
10586 | |||
10587 | op(reg*8+itok.rm); |
||
10588 | |||
10589 | itok.number+=4; |
||
10590 | |||
10591 | reg=r2; |
||
10592 | |||
10593 | break; |
||
10594 | |||
10595 | reg=r1; |
||
10596 | |||
10597 | itok.number&=255; |
||
10598 | |||
10599 | if(reg!=(int)itok.number){ |
||
10600 | |||
10601 | op66(r32); |
||
10602 | |||
10603 | else if((unsigned int)itok.number==AX)op(0x90+reg); |
||
10604 | |||
10605 | op(0x87); |
||
10606 | |||
10607 | } |
||
10608 | |||
10609 | else waralreadinitreg(regs[1][reg],regs[1][itok.number]); |
||
10610 | |||
10611 | reg=r2; |
||
10612 | |||
10613 | } |
||
10614 | |||
10615 | default: swaperror(); break; |
||
10616 | |||
10617 | break; |
||
10618 | |||
10619 | case tk_minusequals: vop+=0x08; |
||
10620 | |||
10621 | case tk_orequals: vop+=0x08; |
||
10622 | |||
10623 | if(CheckAddOnly()){ |
||
10624 | |||
10625 | cha2=' '; |
||
10626 | |||
10627 | else tok=tk_minus; |
||
10628 | |||
10629 | next=0; |
||
10630 | |||
10631 | } |
||
10632 | |||
10633 | if(itok2.type==tp_opperand&&tok!=tk_number&&tok!=tk_undefofs&& |
||
10634 | |||
10635 | CheckMinusNum(); |
||
10636 | |||
10637 | int opost; |
||
10638 | |||
10639 | switch(tok){ |
||
10640 | |||
10641 | case tk_undefofs: |
||
10642 | |||
10643 | rrec=itok.rec; |
||
10644 | |||
10645 | char uname[IDLENGTH]; |
||
10646 | |||
10647 | if(itok.flag&f_extern)goto addnum; |
||
10648 | |||
10649 | case tk_number: |
||
10650 | |||
10651 | next=0; |
||
10652 | |||
10653 | sign=reg1|(reg2*256); |
||
10654 | |||
10655 | op66(r32); |
||
10656 | |||
10657 | if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii); |
||
10658 | |||
10659 | if((postnumflag&f_reloc)!=0)AddReloc(); |
||
10660 | |||
10661 | } |
||
10662 | |||
10663 | ZeroReg(r2,r32); |
||
10664 | |||
10665 | else{ |
||
10666 | |||
10667 | MovRegNum(r32,postnumflag&f_reloc,ii>>=32,reg2); |
||
10668 | |||
10669 | doregmath64(sign); |
||
10670 | |||
10671 | goto addreg; |
||
10672 | |||
10673 | if((postnumflag&f_reloc)==0&&i!=tk_undefofs&&i!=tk_postnumber){ |
||
10674 | |||
10675 | break; |
||
10676 | |||
10677 | addnum: |
||
10678 | |||
10679 | if(r1==AX)op(0x05+vop); |
||
10680 | |||
10681 | op(0x81); |
||
10682 | |||
10683 | } |
||
10684 | |||
10685 | itok.post=opost; |
||
10686 | |||
10687 | else{ |
||
10688 | |||
10689 | if(i==tk_undefofs)AddUndefOff(2,uname); |
||
10690 | |||
10691 | outdword(ii); |
||
10692 | |||
10693 | if(vop==0)vop=0x10; |
||
10694 | |||
10695 | op66(r32); |
||
10696 | |||
10697 | else{ |
||
10698 | |||
10699 | op(0xC0+vop+r2); |
||
10700 | |||
10701 | outdword(ii); |
||
10702 | |||
10703 | case tk_longvar: |
||
10704 | |||
10705 | CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2); |
||
10706 | |||
10707 | outseg(&itok,2); |
||
10708 | |||
10709 | op(r1*8+itok.rm); |
||
10710 | |||
10711 | if(vop==0x20){ //&= |
||
10712 | |||
10713 | } |
||
10714 | |||
10715 | if(vop==0||vop==0x28){ |
||
10716 | |||
10717 | op66(r32); |
||
10718 | |||
10719 | op(0xD0+vop+r2); |
||
10720 | |||
10721 | } |
||
10722 | |||
10723 | break; |
||
10724 | |||
10725 | CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2); |
||
10726 | |||
10727 | for(i=0;i<2;i++){ |
||
10728 | |||
10729 | outseg(&itok,2); |
||
10730 | |||
10731 | op(reg*8+itok.rm); |
||
10732 | |||
10733 | if(i==1)break; |
||
10734 | |||
10735 | itok.number+=4; |
||
10736 | |||
10737 | } |
||
10738 | |||
10739 | case tk_reg64: |
||
10740 | |||
10741 | reg=r1; |
||
10742 | |||
10743 | for(i=0;i<2;i++){ |
||
10744 | |||
10745 | op(0x01+vop); |
||
10746 | |||
10747 | if(i==1)break; |
||
10748 | |||
10749 | if(vop==0x28)vop=0x18; |
||
10750 | |||
10751 | reg=r2; |
||
10752 | |||
10753 | break; |
||
10754 | |||
10755 | op66(r32); |
||
10756 | |||
10757 | op(0xC0+reg+(unsigned int)itok.number*8); |
||
10758 | |||
10759 | ZeroReg(r2,r32); |
||
10760 | |||
10761 | else{ |
||
10762 | |||
10763 | if(vop)vop=8; |
||
10764 | |||
10765 | op(0x83); |
||
10766 | |||
10767 | op(0); |
||
10768 | |||
10769 | } |
||
10770 | |||
10771 | case tk_ID: |
||
10772 | |||
10773 | case tk_proc: |
||
10774 | |||
10775 | case tk_undefproc: |
||
10776 | |||
10777 | unsigned char oaddstack; |
||
10778 | |||
10779 | if(r1==EAX||r2==EAX){ |
||
10780 | |||
10781 | op(0x50); //push AX |
||
10782 | |||
10783 | addESP+=4; |
||
10784 | |||
10785 | addstack=FALSE; |
||
10786 | |||
10787 | if(r1==EDX||r2==EDX){ |
||
10788 | |||
10789 | op(0x50+EDX); //push DX |
||
10790 | |||
10791 | warningreg(regs[1][EDX]); |
||
10792 | |||
10793 | addstack=FALSE; |
||
10794 | |||
10795 | procdo(tk_qword); |
||
10796 | |||
10797 | if(itok2.type==tp_opperand){ |
||
10798 | |||
10799 | doregmath64(EAX|(EDX*256)); |
||
10800 | |||
10801 | } |
||
10802 | |||
10803 | op66(r32); |
||
10804 | |||
10805 | op(0xC0+reg2+EDX*8); //mov reg,EDX |
||
10806 | |||
10807 | op(0x58+EDX); //pop dx |
||
10808 | |||
10809 | } |
||
10810 | |||
10811 | if(r1==EAX||r2==EAX){ |
||
10812 | |||
10813 | op(0x89); |
||
10814 | |||
10815 | op66(r32); |
||
10816 | |||
10817 | addESP-=4; |
||
10818 | |||
10819 | else reg1=EAX; |
||
10820 | |||
10821 | op(0x01+vop); |
||
10822 | |||
10823 | if(vop==0)vop=0x10; |
||
10824 | |||
10825 | op66(r32); |
||
10826 | |||
10827 | op(0xc0+r2+reg2*8); //add reg,ax |
||
10828 | |||
10829 | case tk_bytevar: |
||
10830 | |||
10831 | case tk_beg: |
||
10832 | |||
10833 | case tk_intvar: |
||
10834 | |||
10835 | |||
10836 | |||
10837 | getintoreg64(sign); |
||
10838 | |||
10839 | warningreg(regs[1][reg1]); |
||
10840 | |||
10841 | ClearReg(reg1); |
||
10842 | |||
10843 | op66(r32); |
||
10844 | |||
10845 | op(0xc0+r1+reg1*8); //add reg,ax |
||
10846 | |||
10847 | if(vop==0x28)vop=0x18; |
||
10848 | |||
10849 | op(0x01+vop); |
||
10850 | |||
10851 | next=0; |
||
10852 | |||
10853 | default: valueexpected(); break; |
||
10854 | |||
10855 | break; |
||
10856 | |||
10857 | case tk_llequals: |
||
10858 | |||
10859 | CheckMinusNum(); |
||
10860 | |||
10861 | ii=doconstqwordmath(); |
||
10862 | |||
10863 | if(itok.type==tp_opperand){ |
||
10864 | |||
10865 | op(0xB0+CL); op(ii); //mov CL,num |
||
10866 | |||
10867 | dobegmath(CL); |
||
10868 | |||
10869 | ClearReg(CL); |
||
10870 | |||
10871 | } |
||
10872 | |||
10873 | reg=r1; |
||
10874 | |||
10875 | r2=reg; |
||
10876 | |||
10877 | if(ii<32){ |
||
10878 | |||
10879 | op(0x0F); |
||
10880 | |||
10881 | op(0xC0+r2+r1*8); |
||
10882 | |||
10883 | op66(r32); |
||
10884 | |||
10885 | op(0xD1); op(0xE0+r1+vop); |
||
10886 | |||
10887 | else{ |
||
10888 | |||
10889 | op(0xE0+r1+vop); //shl ax,num |
||
10890 | |||
10891 | } |
||
10892 | |||
10893 | else{ |
||
10894 | |||
10895 | op(0x89); |
||
10896 | |||
10897 | ii-=32; |
||
10898 | |||
10899 | op66(r32); |
||
10900 | |||
10901 | op(0xD1); |
||
10902 | |||
10903 | } |
||
10904 | |||
10905 | op(0xC1); |
||
10906 | |||
10907 | op(ii); |
||
10908 | |||
10909 | } |
||
10910 | |||
10911 | } |
||
10912 | |||
10913 | else if(reg!=CX){ |
||
10914 | |||
10915 | getintobeg(CL,&ofsstr); |
||
10916 | |||
10917 | warningreg(begs[1]); |
||
10918 | |||
10919 | next=0; |
||
10920 | |||
10921 | shiftcl: |
||
10922 | |||
10923 | op(0x0F); |
||
10924 | |||
10925 | if(vop){ |
||
10926 | |||
10927 | r1=r2; |
||
10928 | |||
10929 | } |
||
10930 | |||
10931 | op66(r32); |
||
10932 | |||
10933 | op(0xE0+vop+r1); // SHL xXX,CL |
||
10934 | |||
10935 | else regshifterror(); |
||
10936 | |||
10937 | case tk_multequals: |
||
10938 | |||
10939 | CheckMinusNum(); |
||
10940 | |||
10941 | ii=doconstqwordmath(); |
||
10942 | |||
10943 | if(itok.type==tp_opperand){ |
||
10944 | |||
10945 | op(0x50+r2); |
||
10946 | |||
10947 | op(0x50+r1); |
||
10948 | |||
10949 | MovRegNum(r32,postnumflag&f_reloc,ii,reg1); |
||
10950 | |||
10951 | ConstToReg(ii,reg1,r32); |
||
10952 | |||
10953 | doregmath64(reg1|(reg2*256)); |
||
10954 | |||
10955 | } |
||
10956 | |||
10957 | if((postnumflag&f_reloc)==0){ |
||
10958 | |||
10959 | ZeroReg(r1,r32); |
||
10960 | |||
10961 | break; |
||
10962 | |||
10963 | if(ii==1)break; |
||
10964 | |||
10965 | op66(r32); |
||
10966 | |||
10967 | op(0xC0+9*r1); // ADD r1,r1 |
||
10968 | |||
10969 | op(0x83); |
||
10970 | |||
10971 | op(0); |
||
10972 | |||
10973 | } |
||
10974 | |||
10975 | if(i<32){ |
||
10976 | |||
10977 | outword(0xA40F); |
||
10978 | |||
10979 | op(i); |
||
10980 | |||
10981 | op(0xC1); |
||
10982 | |||
10983 | op(i); |
||
10984 | |||
10985 | else{ |
||
10986 | |||
10987 | op(0x89); |
||
10988 | |||
10989 | i-=32; |
||
10990 | |||
10991 | op66(r32); |
||
10992 | |||
10993 | op(1); |
||
10994 | |||
10995 | } |
||
10996 | |||
10997 | op(0xC1); |
||
10998 | |||
10999 | op(i); |
||
11000 | |||
11001 | } |
||
11002 | |||
11003 | } |
||
11004 | |||
11005 | } |
||
11006 | |||
11007 | op66(r32); |
||
11008 | |||
11009 | op66(r32); |
||
11010 | |||
11011 | addESP+=8; |
||
11012 | |||
11013 | MovRegNum(r32,0,ii>>32,EAX); |
||
11014 | |||
11015 | } |
||
11016 | |||
11017 | op(0x50+r2); |
||
11018 | |||
11019 | op(0x50+r1); |
||
11020 | |||
11021 | reg=ECX|(EAX*256); |
||
11022 | |||
11023 | getintoreg64(reg); |
||
11024 | |||
11025 | mul: |
||
11026 | |||
11027 | addESP-=8; |
||
11028 | |||
11029 | ClearReg(EAX); |
||
11030 | |||
11031 | ClearReg(EDX); |
||
11032 | |||
11033 | next=0; |
||
11034 | |||
11035 | if(r1==EDX){ |
||
11036 | |||
11037 | op66(r32); |
||
11038 | |||
11039 | break; |
||
11040 | |||
11041 | op66(r32); |
||
11042 | |||
11043 | op(0xC0+r2+EDX*8); //mov reg,EDX |
||
11044 | |||
11045 | op(0x89); |
||
11046 | |||
11047 | break; |
||
11048 | |||
11049 | op66(r32); |
||
11050 | |||
11051 | op(0xC0+r1+EAX*8); //mov reg,EAX |
||
11052 | |||
11053 | if(r2!=EDX){ |
||
11054 | |||
11055 | op(0x89); |
||
11056 | |||
11057 | } |
||
11058 | |||
11059 | case tk_divequals: |
||
11060 | |||
11061 | CheckMinusNum(); |
||
11062 | |||
11063 | ii=doconstqwordmath(); |
||
11064 | |||
11065 | if(itok.type==tp_opperand){ |
||
11066 | |||
11067 | MovRegNum(r32,0,ii>>32,reg2); |
||
11068 | |||
11069 | ConstToReg(ii>>32,reg2,r32); |
||
11070 | |||
11071 | op66(r32); |
||
11072 | |||
11073 | op66(r32); |
||
11074 | |||
11075 | addESP+=8; |
||
11076 | |||
11077 | warningreg(regs[1][reg2]); |
||
11078 | |||
11079 | } |
||
11080 | |||
11081 | if(ii==0){ |
||
11082 | |||
11083 | break; |
||
11084 | |||
11085 | if(ii==1)break; |
||
11086 | |||
11087 | if(i<32){ |
||
11088 | |||
11089 | outword(0xAC0F); |
||
11090 | |||
11091 | op(i); |
||
11092 | |||
11093 | op(0xc1); |
||
11094 | |||
11095 | op(i); |
||
11096 | |||
11097 | else{ |
||
11098 | |||
11099 | op(0x89); |
||
11100 | |||
11101 | i-=32; |
||
11102 | |||
11103 | |||
11104 | |||
11105 | op(0xD1); |
||
11106 | |||
11107 | } |
||
11108 | |||
11109 | op(0xC1); |
||
11110 | |||
11111 | op(i); |
||
11112 | |||
11113 | } |
||
11114 | |||
11115 | } |
||
11116 | |||
11117 | } |
||
11118 | |||
11119 | unsigned long number; |
||
11120 | |||
11121 | for(i=0;i<2;i++){ |
||
11122 | |||
11123 | if((postnumflag&f_reloc)==0&&short_ok(number,1)){ |
||
11124 | |||
11125 | op(number); |
||
11126 | |||
11127 | else{ |
||
11128 | |||
11129 | if(i==0&&(postnumflag&f_reloc)!=0)AddReloc(); |
||
11130 | |||
11131 | } |
||
11132 | |||
11133 | number=ii; |
||
11134 | |||
11135 | addESP+=8; |
||
11136 | |||
11137 | } |
||
11138 | |||
11139 | getintoreg64(reg); |
||
11140 | |||
11141 | op66(r32); |
||
11142 | |||
11143 | op66(r32); |
||
11144 | |||
11145 | addESP+=8; |
||
11146 | |||
11147 | warningreg(regs[1][reg2]); |
||
11148 | |||
11149 | divcont: |
||
11150 | |||
11151 | if(r2==EAX){ |
||
11152 | |||
11153 | op66(r32); |
||
11154 | |||
11155 | goto sdiv; |
||
11156 | |||
11157 | op66(r32); |
||
11158 | |||
11159 | op(0xC0+EDX+r2*8); //mov EDX,r2 |
||
11160 | |||
11161 | op(0x89); |
||
11162 | |||
11163 | goto sdiv; |
||
11164 | |||
11165 | op66(r32); |
||
11166 | |||
11167 | op(0xC0+EAX+r1*8); //mov EAX,r1 |
||
11168 | |||
11169 | if(r2!=EDX){ |
||
11170 | |||
11171 | op(0x89); |
||
11172 | |||
11173 | } |
||
11174 | |||
11175 | CallExternProc("__lludiv"); |
||
11176 | |||
11177 | goto endmul; |
||
11178 | |||
11179 | } |
||
11180 | |||
11181 | ClearReg(r2); |
||
11182 | |||
11183 | if(terminater==tk_semicolon)seminext(); |
||
11184 | |||
11185 | } |
||
11186 | |||
11187 | void optnumadd64(unsigned long long num,int r1,int r2,int vop) |
||
11188 | |||
11189 | int i,reg; |
||
11190 | |||
11191 | if(vop==0x20){ //&= |
||
11192 | |||
11193 | for(i=0;i<2;i++){ |
||
11194 | |||
11195 | reg=r2; |
||
11196 | |||
11197 | setzeroflag=TRUE; |
||
11198 | |||
11199 | return; //+= -= |= ^= |
||
11200 | |||
11201 | if(num==1){ |
||
11202 | |||
11203 | op66(r32); |
||
11204 | |||
11205 | op66(r32); |
||
11206 | |||
11207 | op(0xD8+r2); |
||
11208 | |||
11209 | setzeroflag=TRUE; |
||
11210 | |||
11211 | } |
||
11212 | |||
11213 | op66(r32); |
||
11214 | |||
11215 | op66(r32); |
||
11216 | |||
11217 | op(0xD0+r2); |
||
11218 | |||
11219 | setzeroflag=TRUE; |
||
11220 | |||
11221 | } |
||
11222 | |||
11223 | if(vop==8){ //|= |
||
11224 | |||
11225 | if((unsigned short)num<256&&r1<4){ |
||
11226 | |||
11227 | else{ |
||
11228 | |||
11229 | op(0xc8+r1); |
||
11230 | |||
11231 | op(num); |
||
11232 | |||
11233 | } |
||
11234 | |||
11235 | if(r1==AX)op(0x0D); |
||
11236 | |||
11237 | op(0x81); |
||
11238 | |||
11239 | } |
||
11240 | |||
11241 | return; |
||
11242 | |||
11243 | if(num<0x100000000LL){ |
||
11244 | |||
11245 | if(r1==AX)op(0x0D); |
||
11246 | |||
11247 | op(0x81); |
||
11248 | |||
11249 | } |
||
11250 | |||
11251 | return; |
||
11252 | |||
11253 | } |
||
11254 | |||
11255 | if(num>=0xFFFFFFFF00000000LL){ |
||
11256 | |||
11257 | if((unsigned short)num>=0xFF00&&r1<4){ |
||
11258 | |||
11259 | else{ |
||
11260 | |||
11261 | op(0xE0+r1); |
||
11262 | |||
11263 | op(num); |
||
11264 | |||
11265 | } |
||
11266 | |||
11267 | if(r1==AX)op(0x25); |
||
11268 | |||
11269 | op(129); |
||
11270 | |||
11271 | } |
||
11272 | |||
11273 | return; |
||
11274 | |||
11275 | op66(r32); |
||
11276 | |||
11277 | else{ |
||
11278 | |||
11279 | op(0xE0+r1); |
||
11280 | |||
11281 | outdword(num); |
||
11282 | |||
11283 | } |
||
11284 | |||
11285 | reg=r1; |
||
11286 | |||
11287 | for(i=0;i<2;i++){ |
||
11288 | |||
11289 | if(optnumadd(num,reg,r32,vop)==FALSE){ |
||
11290 | |||
11291 | if(short_ok((unsigned long)num,TRUE)){ |
||
11292 | |||
11293 | op(0xC0+vop+reg); |
||
11294 | |||
11295 | } |
||
11296 | |||
11297 | if(reg==EAX)op(5+vop); |
||
11298 | |||
11299 | op(0x81); |
||
11300 | |||
11301 | } |
||
11302 | |||
11303 | } |
||
11304 | |||
11305 | num>>=32; |
||
11306 | |||
11307 | if(vop)vop=8; |
||
11308 | |||
11309 | if(short_ok((unsigned long)num,TRUE)){ |
||
11310 | |||
11311 | op(0xD0+vop+r2); |
||
11312 | |||
11313 | } |
||
11314 | |||
11315 | if(r2==EAX)op(0x15+vop); |
||
11316 | |||
11317 | op(0x81); |
||
11318 | |||
11319 | } |
||
11320 | |||
11321 | } |
||
11322 | |||
11323 | } |
||
11324 | |||
11325 | } |
||
11326 | |||
11327 | } |
||
11328 | |||
11329 | void doregmath64(int reg) |
||
11330 | |||
11331 | int vop,i,optnum,negflag=FALSE; |
||
11332 | |||
11333 | int reg1,reg2; |
||
11334 | |||
11335 | r1=reg&255; |
||
11336 | |||
11337 | Select2FreeReg(r1,r2,®1,®2); |
||
11338 | |||
11339 | if(negflag){ |
||
11340 | |||
11341 | op(0xF7); |
||
11342 | |||
11343 | op66(r32); |
||
11344 | |||
11345 | op(0xD8+r1); // NEG reg |
||
11346 | |||
11347 | op(0x83); |
||
11348 | |||
11349 | op(0); |
||
11350 | |||
11351 | ClearReg(r2); |
||
11352 | |||
11353 | } |
||
11354 | |||
11355 | next=1; |
||
11356 | |||
11357 | if(tok2==tk_number)optnum=OptimNum(); |
||
11358 | |||
11359 | case tk_xor: vop+=0x08; |
||
11360 | |||
11361 | case tk_and: vop+=0x18; |
||
11362 | |||
11363 | case tk_plus: |
||
11364 | |||
11365 | else tok=tk_number; |
||
11366 | |||
11367 | case tk_number: |
||
11368 | |||
11369 | optnumadd64(itok.lnumber,r1,r2,vop); |
||
11370 | |||
11371 | } |
||
11372 | |||
11373 | case tk_undefofs: |
||
11374 | |||
11375 | op66(r32); |
||
11376 | |||
11377 | op(0xC0+vop+r1); |
||
11378 | |||
11379 | else{ |
||
11380 | |||
11381 | else if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
11382 | |||
11383 | outdword(itok.number); |
||
11384 | |||
11385 | if(vop==0x20){ //&= |
||
11386 | |||
11387 | } |
||
11388 | |||
11389 | if(vop==0||vop==0x28){ |
||
11390 | |||
11391 | op66(r32); |
||
11392 | |||
11393 | op(0xD0+vop+r2); |
||
11394 | |||
11395 | } |
||
11396 | |||
11397 | break; |
||
11398 | |||
11399 | case tk_charvar: |
||
11400 | |||
11401 | case tk_bytevar: |
||
11402 | |||
11403 | op66(r32); |
||
11404 | |||
11405 | op(0xC0+r1+reg2*8); /* OPT AX,CX */ |
||
11406 | |||
11407 | ZeroReg(r2,r32); |
||
11408 | |||
11409 | else{ |
||
11410 | |||
11411 | if(vop)vop=8; |
||
11412 | |||
11413 | op(0x83); |
||
11414 | |||
11415 | op(0); |
||
11416 | |||
11417 | } |
||
11418 | |||
11419 | next=0; |
||
11420 | |||
11421 | case tk_reg: |
||
11422 | |||
11423 | outword(0xB70F); |
||
11424 | |||
11425 | op(0xC0+itok.number*9); |
||
11426 | |||
11427 | case tk_reg32: |
||
11428 | |||
11429 | op66(r32); |
||
11430 | |||
11431 | op(0xC0+r1+(unsigned int)itok.number*8); |
||
11432 | |||
11433 | ZeroReg(r2,r32); |
||
11434 | |||
11435 | else{ |
||
11436 | |||
11437 | if(vop)vop=8; |
||
11438 | |||
11439 | op(0x83); |
||
11440 | |||
11441 | op(0); |
||
11442 | |||
11443 | } |
||
11444 | |||
11445 | case tk_reg64: |
||
11446 | |||
11447 | reg=r1; |
||
11448 | |||
11449 | for(i=0;i<2;i++){ |
||
11450 | |||
11451 | op(0x01+vop); |
||
11452 | |||
11453 | if(i==1)break; |
||
11454 | |||
11455 | if(vop==0x28)vop=0x18; |
||
11456 | |||
11457 | reg=r2; |
||
11458 | |||
11459 | break; |
||
11460 | |||
11461 | case tk_dwordvar: |
||
11462 | |||
11463 | op66(r32); |
||
11464 | |||
11465 | op(0x03+vop); |
||
11466 | |||
11467 | outaddress(&itok); |
||
11468 | |||
11469 | ZeroReg(r2,r32); |
||
11470 | |||
11471 | else{ |
||
11472 | |||
11473 | if(vop)vop=8; |
||
11474 | |||
11475 | op(0x83); |
||
11476 | |||
11477 | op(0); |
||
11478 | |||
11479 | } |
||
11480 | |||
11481 | case tk_qwordvar: |
||
11482 | |||
11483 | for(i=0;i<2;i++){ |
||
11484 | |||
11485 | op66(r32); |
||
11486 | |||
11487 | op(0x03+vop); |
||
11488 | |||
11489 | outaddress(&itok); |
||
11490 | |||
11491 | if(vop==0)vop=0x10; |
||
11492 | |||
11493 | itok.number+=4; |
||
11494 | |||
11495 | reg=r2; |
||
11496 | |||
11497 | break; |
||
11498 | |||
11499 | case tk_id: |
||
11500 | |||
11501 | case tk_apiproc: |
||
11502 | |||
11503 | case tk_declare: |
||
11504 | |||
11505 | op66(r32); |
||
11506 | |||
11507 | op(0xc0+r1); |
||
11508 | |||
11509 | if(vop==0)vop=0x10; |
||
11510 | |||
11511 | op66(r32); |
||
11512 | |||
11513 | op(0xc0+r2+EDX*8); |
||
11514 | |||
11515 | break; |
||
11516 | |||
11517 | } |
||
11518 | |||
11519 | case tk_rrminus: |
||
11520 | |||
11521 | regshifterror(); |
||
11522 | |||
11523 | } |
||
11524 | |||
11525 | goto rshift2; |
||
11526 | |||
11527 | getoperand(ECX); |
||
11528 | |||
11529 | op66(r32); |
||
11530 | |||
11531 | op(0xC0+r1+r2*8); |
||
11532 | |||
11533 | op66(r32); |
||
11534 | |||
11535 | op(0xD1); op(0xE8+r2); // SHR reg,1 |
||
11536 | |||
11537 | else if((unsigned int)itok.number!=0){ |
||
11538 | |||
11539 | op(0xe8+r2); // SHR reg,imm8 |
||
11540 | |||
11541 | } |
||
11542 | |||
11543 | else if(r1==ECX||r2==ECX)regshifterror(); |
||
11544 | |||
11545 | else{ |
||
11546 | |||
11547 | getintobeg(CL,&ofsstr); |
||
11548 | |||
11549 | warningreg(begs[1]); |
||
11550 | |||
11551 | op66(r32); |
||
11552 | |||
11553 | op(0xC0+r1+r2*8); |
||
11554 | |||
11555 | op(0xD3); |
||
11556 | |||
11557 | } |
||
11558 | |||
11559 | case tk_llminus: |
||
11560 | |||
11561 | regshifterror(); |
||
11562 | |||
11563 | } |
||
11564 | |||
11565 | goto llshift; |
||
11566 | |||
11567 | getoperand(ECX); |
||
11568 | |||
11569 | op66(r32); |
||
11570 | |||
11571 | op(0xC0+r2+r1*8); |
||
11572 | |||
11573 | op66(r32); |
||
11574 | |||
11575 | op(1); |
||
11576 | |||
11577 | } |
||
11578 | |||
11579 | op(0xC1); |
||
11580 | |||
11581 | op(itok.number); |
||
11582 | |||
11583 | } |
||
11584 | |||
11585 | else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==CL)goto lshift; |
||
11586 | |||
11587 | llshift: |
||
11588 | |||
11589 | next=0; |
||
11590 | |||
11591 | lshift: |
||
11592 | |||
11593 | outword(0xA50F); |
||
11594 | |||
11595 | op66(r32); |
||
11596 | |||
11597 | op(0xE0+r1); // SHL xXX,CL |
||
11598 | |||
11599 | break; |
||
11600 | |||
11601 | case tk_mult: |
||
11602 | |||
11603 | if(negflag&&tok==tk_number){ |
||
11604 | |||
11605 | negflag=FALSE; |
||
11606 | |||
11607 | if(tok==tk_number&&((itok.number&f_reloc)==0)){ |
||
11608 | |||
11609 | ZeroReg(r1,r32); |
||
11610 | |||
11611 | break; |
||
11612 | |||
11613 | if(itok.lnumber==1)break; |
||
11614 | |||
11615 | op66(r32); |
||
11616 | |||
11617 | op(0xC0+9*r1); // ADD r1,r1 |
||
11618 | |||
11619 | op(0x83); |
||
11620 | |||
11621 | op(0); |
||
11622 | |||
11623 | } |
||
11624 | |||
11625 | if(i<32){ |
||
11626 | |||
11627 | outword(0xA40F); |
||
11628 | |||
11629 | op(i); |
||
11630 | |||
11631 | op(0xC1); |
||
11632 | |||
11633 | |||
11634 | |||
11635 | else{ |
||
11636 | |||
11637 | op(0x89); |
||
11638 | |||
11639 | i-=32; |
||
11640 | |||
11641 | op66(r32); |
||
11642 | |||
11643 | op(1); |
||
11644 | |||
11645 | } |
||
11646 | |||
11647 | op(0xC1); |
||
11648 | |||
11649 | op(i); |
||
11650 | |||
11651 | } |
||
11652 | |||
11653 | } |
||
11654 | |||
11655 | } |
||
11656 | |||
11657 | op(0x50+r2); |
||
11658 | |||
11659 | op(0x50+r1); |
||
11660 | |||
11661 | MovRegNum(r32,postnumflag&f_reloc,itok.number,ECX); |
||
11662 | |||
11663 | goto mul; |
||
11664 | |||
11665 | //вызов процедуры __llmul |
||
11666 | |||
11667 | op(0x50+r2); |
||
11668 | |||
11669 | op(0x50+r1); |
||
11670 | |||
11671 | reg=ECX|(EAX*256); |
||
11672 | |||
11673 | // doregmath64(reg); |
||
11674 | |||
11675 | mul: |
||
11676 | |||
11677 | addESP-=8; |
||
11678 | |||
11679 | if(r1!=EAX){ |
||
11680 | |||
11681 | if(r2==EAX){ |
||
11682 | |||
11683 | op(0x90+EDX); |
||
11684 | |||
11685 | } |
||
11686 | |||
11687 | op(0x89); |
||
11688 | |||
11689 | op66(r32); |
||
11690 | |||
11691 | op(0xC0+r1+EAX*8); //mov reg,EAX |
||
11692 | |||
11693 | } |
||
11694 | |||
11695 | op(0x89); |
||
11696 | |||
11697 | } |
||
11698 | |||
11699 | op66(r32); |
||
11700 | |||
11701 | op(0xC0+r2+EDX*8); //mov reg,EDX |
||
11702 | |||
11703 | break; |
||
11704 | |||
11705 | case tk_mod: |
||
11706 | |||
11707 | goto divcalc;; |
||
11708 | |||
11709 | case tk_div: |
||
11710 | |||
11711 | getoperand(reg1); |
||
11712 | |||
11713 | itok.lnumber=-itok.lnumber; |
||
11714 | |||
11715 | } |
||
11716 | |||
11717 | if(itok.lnumber==0){ |
||
11718 | |||
11719 | break; |
||
11720 | |||
11721 | if(itok.lnumber==1){ |
||
11722 | |||
11723 | ZeroReg(r1,r32); |
||
11724 | |||
11725 | } |
||
11726 | |||
11727 | } |
||
11728 | |||
11729 | if(vop){ //mod |
||
11730 | |||
11731 | } |
||
11732 | |||
11733 | if(i<32){ |
||
11734 | |||
11735 | outword(0xAC0F); |
||
11736 | |||
11737 | op(i); |
||
11738 | |||
11739 | op(0xc1); |
||
11740 | |||
11741 | op(i); |
||
11742 | |||
11743 | else{ |
||
11744 | |||
11745 | op(0x89); |
||
11746 | |||
11747 | i-=32; |
||
11748 | |||
11749 | op66(r32); |
||
11750 | |||
11751 | op(0xD1); |
||
11752 | |||
11753 | } |
||
11754 | |||
11755 | op(0xC1); |
||
11756 | |||
11757 | op(i); |
||
11758 | |||
11759 | } |
||
11760 | |||
11761 | } |
||
11762 | |||
11763 | break; |
||
11764 | |||
11765 | unsigned long number; |
||
11766 | |||
11767 | for(i=0;i<2;i++){ |
||
11768 | |||
11769 | if((itok.flag&f_reloc)==0&&short_ok(number,1)){ |
||
11770 | |||
11771 | op(number); |
||
11772 | |||
11773 | else{ |
||
11774 | |||
11775 | if(i==0&&(itok.flag&f_reloc)!=0)AddReloc(); |
||
11776 | |||
11777 | } |
||
11778 | |||
11779 | number=itok.number; |
||
11780 | |||
11781 | addESP+=8; |
||
11782 | |||
11783 | } |
||
11784 | |||
11785 | getintoreg64(reg); |
||
11786 | |||
11787 | op(0x50+reg2); |
||
11788 | |||
11789 | op(0x50+reg1); |
||
11790 | |||
11791 | next=0; |
||
11792 | |||
11793 | if(r1!=EAX){ |
||
11794 | |||
11795 | if(r1==EDX){ |
||
11796 | |||
11797 | op(0x90+EDX); |
||
11798 | |||
11799 | } |
||
11800 | |||
11801 | op(0x89); |
||
11802 | |||
11803 | op66(r32); |
||
11804 | |||
11805 | op(0xC0+EAX+r1*8); //mov EAX,r1 |
||
11806 | |||
11807 | } |
||
11808 | |||
11809 | op(0x89); |
||
11810 | |||
11811 | } |
||
11812 | |||
11813 | op66(r32); |
||
11814 | |||
11815 | op(0xC0+EDX+r2*8); //mov EDX,r2 |
||
11816 | |||
11817 | sdiv: |
||
11818 | |||
11819 | addESP-=8; |
||
11820 | |||
11821 | default: operatorexpected(); break; |
||
11822 | |||
11823 | if(next)nexttok(); |
||
11824 | |||
11825 | ClearReg(r1); |
||
11826 | |||
11827 | if(cpu<3)cpu=3; |
||
11828 | |||
11829 | |||
11830 | |||
11831 | { |
||
11832 | |||
11833 | unsigned long long holdnumber=0; |
||
11834 | |||
11835 | int reg1,reg2; |
||
11836 | |||
11837 | r2=reg/256; |
||
11838 | |||
11839 | if(tok==tk_minus){ |
||
11840 | |||
11841 | negflag=1; |
||
11842 | |||
11843 | } |
||
11844 | |||
11845 | switch(tok){ |
||
11846 | |||
11847 | holdnumber=CalcNumber(4); |
||
11848 | |||
11849 | MovRegNum(r32,0,holdnumber>>32,r2); |
||
11850 | |||
11851 | break; |
||
11852 | |||
11853 | case tk_undefofs: |
||
11854 | |||
11855 | op66(r32); |
||
11856 | |||
11857 | if(tok==tk_apioffset)AddApiToPost(itok.number); |
||
11858 | |||
11859 | if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
11860 | |||
11861 | tok=tk_number; |
||
11862 | |||
11863 | outdword(holdnumber); |
||
11864 | |||
11865 | |||
11866 | |||
11867 | ClearReg(r1); |
||
11868 | |||
11869 | break; |
||
11870 | |||
11871 | CheckAllMassiv(bufrm,8,&strinf,&itok,reg1,reg2); |
||
11872 | |||
11873 | op66(r32); |
||
11874 | |||
11875 | if(itok.post==0)outseg(&itok,2); |
||
11876 | |||
11877 | op(r1*8+itok.rm); |
||
11878 | |||
11879 | if((itok.flag&f_extern)==0){ |
||
11880 | |||
11881 | if(am32&&itok.rm==rm_sib)outptr++; |
||
11882 | |||
11883 | outptr=ooutptr; |
||
11884 | |||
11885 | else setwordext(&itok.number); |
||
11886 | |||
11887 | outaddress(&itok); |
||
11888 | |||
11889 | |||
11890 | |||
11891 | break; |
||
11892 | |||
11893 | reg=r1; |
||
11894 | |||
11895 | if(reg==EAX&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){ |
||
11896 | |||
11897 | outseg(&itok,1); |
||
11898 | |||
11899 | if(itok.post==UNDEF_OFSET)AddUndefOff(2,itok.name); |
||
11900 | |||
11901 | else outdword(itok.number); |
||
11902 | |||
11903 | else{ |
||
11904 | |||
11905 | op66(r32); |
||
11906 | |||
11907 | op(0x8B); |
||
11908 | |||
11909 | outaddress(&itok); |
||
11910 | |||
11911 | |||
11912 | |||
11913 | itok.number+=4; |
||
11914 | |||
11915 | |||
11916 | |||
11917 | break; |
||
11918 | |||
11919 | case tk_dwordvar: |
||
11920 | |||
11921 | op66(r32); |
||
11922 | |||
11923 | op(0xA1); |
||
11924 | |||
11925 | if(am32==FALSE)outword((unsigned int)itok.number); |
||
11926 | |||
11927 | } |
||
11928 | |||
11929 | CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2); |
||
11930 | |||
11931 | outseg(&itok,2); |
||
11932 | |||
11933 | op(r1*8+itok.rm); |
||
11934 | |||
11935 | } |
||
11936 | |||
11937 | ClearReg(r1); |
||
11938 | |||
11939 | case tk_intvar: |
||
11940 | |||
11941 | CheckAllMassiv(bufrm,2,&strinf,&itok,reg1,reg2); |
||
11942 | |||
11943 | ZeroReg(r1,r32); |
||
11944 | |||
11945 | outseg(&itok,2); //mov reg,var |
||
11946 | |||
11947 | } |
||
11948 | |||
11949 | op66(r32); |
||
11950 | |||
11951 | op(0x0F); op(tok==tk_wordvar?0xB7:0xBF); |
||
11952 | |||
11953 | op(r1*8+itok.rm); |
||
11954 | |||
11955 | ClearReg(r1); |
||
11956 | |||
11957 | break; |
||
11958 | |||
11959 | case tk_charvar: |
||
11960 | |||
11961 | if(reg<=EBX&&tok==tk_bytevar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ |
||
11962 | |||
11963 | outseg(&itok,2); |
||
11964 | |||
11965 | } |
||
11966 | |||
11967 | op66(r32); |
||
11968 | |||
11969 | op(0xf); |
||
11970 | |||
11971 | else op(0xbe); |
||
11972 | |||
11973 | op(r1*8+itok.rm); // MOVZX regL,[byte] |
||
11974 | |||
11975 | ClearReg(r1); |
||
11976 | |||
11977 | break; |
||
11978 | |||
11979 | if(tok2==tk_openbracket){ //вызов процедуры по адресу в регистре |
||
11980 | |||
11981 | nexttok(); |
||
11982 | |||
11983 | if(comfile==file_w32)swapparam(); |
||
11984 | |||
11985 | op66(r16); |
||
11986 | |||
11987 | op(0xD0+reg1); /* CALL reg with stack params */ |
||
11988 | |||
11989 | clearregstat(); |
||
11990 | |||
11991 | FreeGlobalConst(); |
||
11992 | |||
11993 | } |
||
11994 | |||
11995 | ZeroReg(r1,r32); |
||
11996 | |||
11997 | op(0xC0+r1+(unsigned int)itok.number*8); |
||
11998 | |||
11999 | else{ |
||
12000 | |||
12001 | outword(0xB70F); |
||
12002 | |||
12003 | } |
||
12004 | |||
12005 | ZeroReg(r2,r32); |
||
12006 | |||
12007 | case tk_reg32: |
||
12008 | |||
12009 | reg1=itok.number; |
||
12010 | |||
12011 | param[0]=0; |
||
12012 | |||
12013 | else doparams(); |
||
12014 | |||
12015 | op(0xFF); |
||
12016 | |||
12017 | itok.number=0; |
||
12018 | |||
12019 | #ifdef OPTVARCONST |
||
12020 | |||
12021 | #endif |
||
12022 | |||
12023 | if(r1!=(int)itok.number){ |
||
12024 | |||
12025 | op(0x89); |
||
12026 | |||
12027 | RegToReg(r1,itok.number,r32); |
||
12028 | |||
12029 | ZeroReg(r2,r32); |
||
12030 | |||
12031 | case tk_reg64: |
||
12032 | |||
12033 | reg2=itok.number/256; |
||
12034 | |||
12035 | if(r1==reg2){ |
||
12036 | |||
12037 | op66(r32); |
||
12038 | |||
12039 | else if(r2==AX)op(0x90+r1); |
||
12040 | |||
12041 | op(0x87); |
||
12042 | |||
12043 | } |
||
12044 | |||
12045 | } |
||
12046 | |||
12047 | temp=r2; |
||
12048 | |||
12049 | r1=temp; |
||
12050 | |||
12051 | reg2=reg1; |
||
12052 | |||
12053 | } |
||
12054 | |||
12055 | int temp; |
||
12056 | |||
12057 | r2=r1; |
||
12058 | |||
12059 | temp=reg2; |
||
12060 | |||
12061 | reg1=temp; |
||
12062 | |||
12063 | if(r1!=reg1){ |
||
12064 | |||
12065 | op(0x89); |
||
12066 | |||
12067 | RegToReg(r1,reg1,r32); |
||
12068 | |||
12069 | if(r2!=reg2){ |
||
12070 | |||
12071 | op(0x89); |
||
12072 | |||
12073 | RegToReg(r2,reg2,r32); |
||
12074 | |||
12075 | break; |
||
12076 | |||
12077 | int vops; |
||
12078 | |||
12079 | if(i<=64)vops=r64; |
||
12080 | |||
12081 | if(i<=16)vops=r16; |
||
12082 | |||
12083 | ZeroReg(r2,r32); |
||
12084 | |||
12085 | case tk_seg: |
||
12086 | |||
12087 | op(0x8C); |
||
12088 | |||
12089 | ClearReg(r1); |
||
12090 | |||
12091 | break; |
||
12092 | |||
12093 | if(optimizespeed&&chip>3&&chip<7&®<4&®!=(int)(itok.number%4)){ |
||
12094 | |||
12095 | op(0x88); |
||
12096 | |||
12097 | } |
||
12098 | |||
12099 | op66(r32); |
||
12100 | |||
12101 | op(0xC0+r1*8+(unsigned int)itok.number); // MOVZX regL,beg |
||
12102 | |||
12103 | ClearReg(reg); |
||
12104 | |||
12105 | break; |
||
12106 | |||
12107 | getoperand(am32==FALSE?BX:reg); |
||
12108 | |||
12109 | case tk_ID: |
||
12110 | |||
12111 | case tk_proc: |
||
12112 | |||
12113 | case tk_undefproc: |
||
12114 | |||
12115 | if((!i)||macros(tk_qword)==0)procdo(tk_qword); |
||
12116 | |||
12117 | goto movreg64; |
||
12118 | |||
12119 | op66(r32); |
||
12120 | |||
12121 | outdword(addpoststring()); |
||
12122 | |||
12123 | ZeroReg(r2,r32); |
||
12124 | |||
12125 | default: valueexpected(); break; |
||
12126 | |||
12127 | if(negflag){ |
||
12128 | |||
12129 | op(0xF7); |
||
12130 | |||
12131 | op66(r32); |
||
12132 | |||
12133 | op(0xD8+r1); // NEG reg |
||
12134 | |||
12135 | op(0x83); |
||
12136 | |||
12137 | op(0); |
||
12138 | |||
12139 | ClearReg(r2); |
||
12140 | |||
12141 | if(next)nexttok(); |
||
12142 | |||
12143 | |||
12144 | |||
12145 | { |
||
12146 | |||
12147 | int tok4=tk_id; |
||
12148 | |||
12149 | struct idrec *ptrs; |
||
12150 | |||
12151 | strcpy(string4,name); |
||
12152 | |||
12153 | ptrs=itok4.rec; |
||
12154 | |||
12155 | case tk_id: |
||
12156 | |||
12157 | itok4=itok; |
||
12158 | |||
12159 | string[0]=0; |
||
12160 | |||
12161 | tok=tk_undefproc; |
||
12162 | |||
12163 | itok.segm=NOT_DYNAMIC; |
||
12164 | |||
12165 | itok.post=0; |
||
12166 | |||
12167 | addacall(secondcallnum++,CALL_NEAR); |
||
12168 | |||
12169 | itok=itok4; |
||
12170 | |||
12171 | break; |
||
12172 | |||
12173 | ptrs->rectok=tk_undefproc; |
||
12174 | |||
12175 | addacall(itok4.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR)); |
||
12176 | |||
12177 | break; |
||
12178 | |||
12179 | if(itok4.segm==DYNAMIC)itok4.segm=ptrs->recsegm=DYNAMIC_USED; |
||
12180 | |||
12181 | addacall(itok4.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR)); |
||
12182 | |||
12183 | } |
||
12184 | |||
12185 | callloc(itok4.number); |
||
12186 | |||
12187 | break; |
||
12188 | |||
12189 | sprintf(string4,"'%s' already used",name); |
||
12190 | |||
12191 | break; |
||
12192 | |||
12193 | } |
||
12194 | |||
12195 | >7&®<4&®!=(int)(itok.number%4)){ |
||
12196 | |||
12197 | >=16)vops=r16; |
||
12198 | |||
12199 | >=64)vops=r64; |
||
12200 | |||
12201 | >7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ |
||
12202 | |||
12203 | >2;i++){ |
||
12204 | |||
12205 | } |
||
12206 | |||
12207 | void>2;i++){ |
||
12208 | |||
12209 | >32){ |
||
12210 | |||
12211 | >2;i++){ |
||
12212 | |||
12213 | >4){ |
||
12214 | |||
12215 | >4){ |
||
12216 | |||
12217 | >65536){ |
||
12218 | |||
12219 | >3)cpu=3; |
||
12220 | |||
12221 | |||
12222 | |||
12223 | >32){ |
||
12224 | |||
12225 | >32){ |
||
12226 | |||
12227 | >2;i++){ |
||
12228 | |||
12229 | >2;i++){ |
||
12230 | |||
12231 | >2;i++){ |
||
12232 | |||
12233 | >2;i++){ |
||
12234 | |||
12235 | >2;i++){ |
||
12236 | |||
12237 | >2;i++){ |
||
12238 | |||
12239 | >2;i++){ |
||
12240 | |||
12241 | >2;i++){ |
||
12242 | |||
12243 | >=tk_float)*otok=tk_charvar+wtok-> |
||
12244 | |||
12245 | >256&&razr==r16)razr=r8; |
||
12246 | |||
12247 | > |
||
12248 | |||
12249 | >17){ |
||
12250 | |||
12251 | >65536&&optimizespeed&&(itok.flag&f_reloc)==0&&sign==0){>2&&razr==r16){ |
||
12252 | |||
12253 | >=16)next=r16; |
||
12254 | |||
12255 | >=64)next=r64; |
||
12256 | |||
12257 | > |
||
12258 | |||
12259 | >=32)vops=r32; |
||
12260 | |||
12261 | >2)regmathoperror(); |
||
12262 | |||
12263 | >2&&razr==r16)regmathoperror(); |
||
12264 | |||
12265 | >2&&razr==r16){ |
||
12266 | |||
12267 | >=STACK_SIZE32)(postbuf+posts)-> |
||
12268 | |||
12269 | } |
||
12270 | |||
12271 | void>128){ |
||
12272 | |||
12273 | >4){ |
||
12274 | |||
12275 | >2;i++){ |
||
12276 | |||
12277 | >7){ |
||
12278 | |||
12279 | >3)cpu=3; |
||
12280 | |||
12281 | |||
12282 | |||
12283 | >2;i++){ |
||
12284 | |||
12285 | >=8)vops=r8; |
||
12286 | |||
12287 | >=32)vops=r32; |
||
12288 | |||
12289 | >4?beg:beg-4),i); |
||
12290 | |||
12291 | //>4&®!=(int)(itok.number%4)){ |
||
12292 | |||
12293 | > |
||
12294 | |||
12295 | >=32)vops=r32; |
||
12296 | |||
12297 | >7&®!=(int)itok.number){ |
||
12298 | |||
12299 | >7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ |
||
12300 | |||
12301 | >3)cpu=3; |
||
12302 | |||
12303 | >1)begmathoperror(); |
||
12304 | |||
12305 | >2)begmathoperror(); |
||
12306 | |||
12307 | >=16)vops=r16; |
||
12308 | |||
12309 | >=64)vops=r64; |
||
12310 | |||
12311 | >3)cpu=3; |
||
12312 | |||
12313 | |||
12314 | |||
12315 | >2&®==CX){ |
||
12316 | |||
12317 | >=16)vops=r16; |
||
12318 | |||
12319 | >=64)vops=r64; |
||
12320 | |||
12321 | >2)cpu=2; |
||
12322 | |||
12323 | >2)goto> |
||
12324 | |||
12325 | >4){ |
||
12326 | |||
12327 | >256&&razr==r16&®<4){ |
||
12328 | |||
12329 | >3)cpu=3; |
||
12330 | |||
12331 | >2))){ |
||
12332 | |||
12333 | >2&&razr==r16){ |
||
12334 | |||
12335 | >2)cpu=2; |
||
12336 | |||
12337 | >=16)razr=r16; |
||
12338 | |||
12339 | >=64)razr=r64; |
||
12340 | |||
12341 | >1){ |
||
12342 | |||
12343 | >=16)razr=r16; |
||
12344 | |||
12345 | >=64)razr=r64; |
||
12346 | |||
12347 | >2){ |
||
12348 | |||
12349 | >=16)razr=r16; |
||
12350 | |||
12351 | >=64)razr=r64; |
||
12352 | |||
12353 | >=tk_doublevar&&itok.npointr==0){ |
||
12354 | |||
12355 | >=8)razr=r8; |
||
12356 | |||
12357 | >=32)razr=r32; |
||
12358 | |||
12359 | >3)cpu=3; |
||
12360 | |||
12361 | |||
12362 | |||
12363 | >=16)vops=r16; |
||
12364 | |||
12365 | >=64)vops=r64; |
||
12366 | |||
12367 | >=16)vops=r16; |
||
12368 | |||
12369 | >=64)vops=r64; |
||
12370 | |||
12371 | > |
||
12372 | |||
12373 | } |
||
12374 | |||
12375 | int>7){ |
||
12376 | |||
12377 | >7)goto>3)cpu=3; |
||
12378 | |||
12379 | >=32)i=r32; |
||
12380 | |||
12381 | >2)cpu=2; |
||
12382 | |||
12383 | >=tk_doublevar&&itok.npointr==0){ |
||
12384 | |||
12385 | >2)cpu=2; |
||
12386 | |||
12387 | >3)cpu=3; |
||
12388 | |||
12389 | > |
||
12390 | |||
12391 | >2){ |
||
12392 | |||
12393 | >4){ |
||
12394 | |||
12395 | >17){ |
||
12396 | |||
12397 | >=wtok.npointr)getpointeradr(&wtok,wbuf,&wstr,npointr-1,razr,BX); |
||
12398 | |||
12399 | >7&&*expand==FALSE&&optimizespeed&&speedmul32(num,reg,razr))break; |
||
12400 | |||
12401 | >2)cpu=2; |
||
12402 | |||
12403 | >1&&razr==r16){ |
||
12404 | |||
12405 | > |
||
12406 | |||
12407 | >3){ |
||
12408 | |||
12409 | >2||val>3)+base); |
||
12410 | |||
12411 | >6)+(idx<<3)+base); |
||
12412 | |||
12413 | >6)); |
||
12414 | |||
12415 | >=0)*zoom=z; |
||
12416 | |||
12417 | >15;i++){ |
||
12418 | |||
12419 | >24;i++){ |
||
12420 | |||
12421 |