Rev 7545 | Go to most recent revision | Details | Compare with Previous | 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 | |||
7626 | siemargl | 1387 | if((flag&f_reloc)!=0)AddReloc(); |
1388 | razr==r16?outword((unsigned int)num):outdword(num); |
||
1389 | op66(razr); |
||
1390 | if(sign)outword(0xE9F7); /* IMUL CX */ |
||
6446 | GerdtR | 1391 | |
1392 | ConstToReg(num,CX,razr); |
||
1393 | |||
1394 | } |
||
1395 | |||
1396 | op66(r16); |
||
1397 | |||
1398 | op66(r16); |
||
1399 | |||
1400 | outword(num); //mov DX,num |
||
1401 | |||
1402 | op(0xF7); |
||
1403 | |||
1404 | op66(r16); |
||
1405 | |||
1406 | warningreg(regs[0][reg!=DX?2:1]); |
||
1407 | |||
1408 | } |
||
1409 | |||
1410 | else{ |
||
1411 | |||
1412 | op66(razr); |
||
1413 | |||
1414 | op(0xc0+reg*9); |
||
1415 | |||
1416 | else{ |
||
1417 | |||
1418 | razr==r16?outword((unsigned int)num):outdword(num); |
||
1419 | |||
1420 | } |
||
1421 | |||
1422 | break; |
||
1423 | |||
1424 | } |
||
1425 | |||
1426 | /* --------------- byte, char, word, int math starts ----------------- */ |
||
1427 | |||
1428 | long long CalcNumber(int sign) |
||
1429 | |||
1430 | long long hold; |
||
1431 | |||
1432 | case 0: |
||
1433 | |||
1434 | break; |
||
1435 | |||
1436 | hold=doconstlongmath(); |
||
1437 | |||
1438 | case 2: |
||
1439 | |||
1440 | break; |
||
1441 | |||
1442 | hold=doconstdoublemath(); |
||
1443 | |||
1444 | default: |
||
1445 | |||
1446 | break; |
||
1447 | |||
1448 | return hold; |
||
1449 | |||
1450 | |||
1451 | |||
1452 | /*-----------------11.09.00 12:44------------------- |
||
1453 | |||
1454 | --------------------------------------------------*/ |
||
1455 | |||
1456 | ITOK oitok=itok; |
||
1457 | |||
1458 | unsigned int oinptr=inptr2; |
||
1459 | |||
1460 | int otype2=itok2.type; |
||
1461 | |||
1462 | // printf("tok=%d num=%d type=%d\n",tok,itok.number,itok.type); |
||
1463 | |||
1464 | return TRUE; //только цифры |
||
1465 | |||
1466 | cha2=ocha; //востановить исходное состояние |
||
1467 | |||
1468 | tok2=otok2; |
||
1469 | |||
1470 | itok=oitok; |
||
1471 | |||
1472 | if(bufrm){ |
||
1473 | |||
1474 | |||
1475 | |||
1476 | if(strinf.bufstr){ |
||
1477 | |||
1478 | strinf.bufstr=NULL; |
||
1479 | |||
1480 | return FALSE; |
||
1481 | |||
1482 | |||
1483 | |||
1484 | { |
||
1485 | |||
1486 | ITOK wtok; |
||
1487 | |||
1488 | SINFO wstr; |
||
1489 | |||
1490 | if(tok!=type)illegalfloat(); |
||
1491 | |||
1492 | strinf.bufstr=NULL; |
||
1493 | |||
1494 | wbuf=bufrm; |
||
1495 | |||
1496 | otok=tok; |
||
1497 | |||
1498 | // getoperand(); |
||
1499 | |||
1500 | nexttok(); |
||
1501 | |||
1502 | while(tok==tk_mult){ |
||
1503 | |||
1504 | numpointr++; |
||
1505 | |||
1506 | if(numpointr>itok.npointr)unuseableinput(); |
||
1507 | |||
1508 | else{ |
||
1509 | |||
1510 | if(tok==tk_floatvar&&tok2==tk_semicolon){ |
||
1511 | |||
1512 | do_e_axmath(1,r32,&ofsstr); |
||
1513 | |||
1514 | else doeaxfloatmath(tk_reg32,AX); |
||
1515 | |||
1516 | if(otok==tk_pointer){ |
||
1517 | |||
1518 | wtok.rm=wtok.sib; |
||
1519 | |||
1520 | else wtok.sib=CODE16; |
||
1521 | |||
1522 | } |
||
1523 | |||
1524 | int razr=typesize(itok.type); |
||
1525 | |||
1526 | else unuseableinput(); |
||
1527 | |||
1528 | } |
||
1529 | |||
1530 | if((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0))){ |
||
1531 | |||
1532 | outseg(&wtok,1); |
||
1533 | |||
1534 | if(wtok.post==UNDEF_OFSET){ |
||
1535 | |||
1536 | wtok.post=0; |
||
1537 | |||
1538 | if(am32==FALSE)outword(wtok.number); //???? |
||
1539 | |||
1540 | } |
||
1541 | |||
1542 | CheckAllMassiv(wbuf,r32,&wstr,&wtok); |
||
1543 | |||
1544 | outseg(&wtok,2); |
||
1545 | |||
1546 | outaddress(&wtok); |
||
1547 | |||
1548 | } |
||
1549 | |||
1550 | int MultiAssign(int razr,int usereg,int npointr) |
||
1551 | |||
1552 | int otok; |
||
1553 | |||
1554 | char *wbuf; |
||
1555 | |||
1556 | int sign=0,rettype,nrazr,posiblret,pointr=0; |
||
1557 | |||
1558 | int ureg; |
||
1559 | |||
1560 | wstr=strinf; |
||
1561 | |||
1562 | wtok=itok; |
||
1563 | |||
1564 | bufrm=NULL; |
||
1565 | |||
1566 | if(tok==tk_bits){ |
||
1567 | |||
1568 | nrazr=r32; |
||
1569 | |||
1570 | int i=itok.bit.siz+itok.bit.ofs; |
||
1571 | |||
1572 | nrazr=r8; |
||
1573 | |||
1574 | } |
||
1575 | |||
1576 | rettype=tk_word; |
||
1577 | |||
1578 | } |
||
1579 | |||
1580 | } |
||
1581 | |||
1582 | nrazr=GetVarSize(tok); |
||
1583 | |||
1584 | case tk_beg: |
||
1585 | |||
1586 | if(ureg>3)ureg-=4; |
||
1587 | |||
1588 | break; |
||
1589 | |||
1590 | case tk_reg32: |
||
1591 | |||
1592 | break; |
||
1593 | |||
1594 | // if(tok==tk_beg)usereg|=USEFIRST4REG; |
||
1595 | |||
1596 | posiblret=nrazr; |
||
1597 | |||
1598 | switch ( razr ) { |
||
1599 | |||
1600 | rettype=tk_byte; |
||
1601 | |||
1602 | case r16: |
||
1603 | |||
1604 | break; |
||
1605 | |||
1606 | rettype=tk_dword; |
||
1607 | |||
1608 | } |
||
1609 | |||
1610 | int numpointr=0; |
||
1611 | |||
1612 | nexttok(); |
||
1613 | |||
1614 | while(tok==tk_mult){ |
||
1615 | |||
1616 | numpointr++; |
||
1617 | |||
1618 | if(numpointr>itok.npointr){ |
||
1619 | |||
1620 | } |
||
1621 | |||
1622 | if(tok2==tk_assign){ |
||
1623 | |||
1624 | if(ofsstr){ |
||
1625 | |||
1626 | ofsstr=NULL; |
||
1627 | |||
1628 | } |
||
1629 | |||
1630 | if(tok==tk_pointer){ |
||
1631 | |||
1632 | if(reg==ureg)reg=idxregs[1]; |
||
1633 | |||
1634 | } |
||
1635 | |||
1636 | switch(tok){ |
||
1637 | |||
1638 | case tk_reg32: |
||
1639 | |||
1640 | break; |
||
1641 | |||
1642 | usereg=(itok.number>3?itok.number-4:itok.number); |
||
1643 | |||
1644 | default: |
||
1645 | |||
1646 | break; |
||
1647 | |||
1648 | } |
||
1649 | |||
1650 | case tk_char: |
||
1651 | |||
1652 | if(tok2==tk_semicolon&&usereg!=0&&usereg<4){ |
||
1653 | |||
1654 | // if(tok==tk_beg&&itok.number<4)ureg=hnumber=itok.number; |
||
1655 | |||
1656 | } |
||
1657 | |||
1658 | if((usereg==1&&itok.number<4)||usereg==0){ |
||
1659 | |||
1660 | nexttok(); |
||
1661 | |||
1662 | } |
||
1663 | |||
1664 | else doalmath(sign,&ofsstr); |
||
1665 | |||
1666 | break; |
||
1667 | |||
1668 | case tk_word: |
||
1669 | |||
1670 | ureg=hnumber=usereg; |
||
1671 | |||
1672 | getintoreg(usereg,r16,sign,&ofsstr); |
||
1673 | |||
1674 | else do_e_axmath(sign,r16,&ofsstr); |
||
1675 | |||
1676 | break; |
||
1677 | |||
1678 | doeaxfloatmath(tk_reg32,AX); |
||
1679 | |||
1680 | default: |
||
1681 | |||
1682 | ureg=hnumber=usereg; |
||
1683 | |||
1684 | getintoreg(usereg,r32,sign,&ofsstr); |
||
1685 | |||
1686 | else{ |
||
1687 | |||
1688 | do_e_axmath(sign,r32,&ofsstr); |
||
1689 | |||
1690 | if(ofsstr)IDZToReg(ofsstr,usereg,r32); |
||
1691 | |||
1692 | } |
||
1693 | |||
1694 | if(ofsstr){ |
||
1695 | |||
1696 | ofsstr=NULL; |
||
1697 | |||
1698 | switch ( nrazr ) { |
||
1699 | |||
1700 | posiblret=tk_byte; |
||
1701 | |||
1702 | case r16: |
||
1703 | |||
1704 | break; |
||
1705 | |||
1706 | posiblret=tk_dword; |
||
1707 | |||
1708 | } |
||
1709 | |||
1710 | if(otok==tk_pointer)cwpointr(&wtok,wbuf,&wstr,&otok,npointr,ureg); |
||
1711 | |||
1712 | case tk_intvar: |
||
1713 | |||
1714 | case tk_longvar: |
||
1715 | |||
1716 | case tk_floatvar: |
||
1717 | |||
1718 | CheckRegToConst(hnumber,&wtok,otok>tk_wordvar?r32:r16); |
||
1719 | |||
1720 | KillVar(wtok.name); |
||
1721 | |||
1722 | if(hnumber==0&&((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
1723 | |||
1724 | outseg(&wtok,1); |
||
1725 | |||
1726 | if(wtok.post==UNDEF_OFSET){ |
||
1727 | |||
1728 | wtok.post=0; |
||
1729 | |||
1730 | if(am32==FALSE)outword(wtok.number); //???? |
||
1731 | |||
1732 | } |
||
1733 | |||
1734 | CheckAllMassiv(wbuf,nrazr,&wstr,&wtok); |
||
1735 | |||
1736 | outseg(&wtok,2); |
||
1737 | |||
1738 | outaddress(&wtok); |
||
1739 | |||
1740 | break; |
||
1741 | |||
1742 | case tk_bytevar: |
||
1743 | |||
1744 | CheckRegToConst(hnumber,&wtok,r8); |
||
1745 | |||
1746 | KillVar(wtok.name); |
||
1747 | |||
1748 | if(hnumber==0&&((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
1749 | |||
1750 | op(0xA2); /* MOV [byte],AL */ |
||
1751 | |||
1752 | AddUndefOff(2,wtok.name); |
||
1753 | |||
1754 | } |
||
1755 | |||
1756 | else outdword(wtok.number); |
||
1757 | |||
1758 | else{ |
||
1759 | |||
1760 | outseg(&wtok,2); /* MOV [rmbyte],AL */ |
||
1761 | |||
1762 | op(wtok.rm+hnumber*8); |
||
1763 | |||
1764 | } |
||
1765 | |||
1766 | case tk_bits: |
||
1767 | |||
1768 | op66(nrazr==r32?r32:r16); |
||
1769 | |||
1770 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4; |
||
1771 | |||
1772 | op66(nrazr==r32?r32:r16); |
||
1773 | |||
1774 | } |
||
1775 | |||
1776 | op66(r32); |
||
1777 | |||
1778 | int siz=wtok.bit.siz; |
||
1779 | |||
1780 | op(0x50); //push eax |
||
1781 | |||
1782 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; |
||
1783 | |||
1784 | |||
1785 | |||
1786 | op66(r32); //shr eax,size |
||
1787 | |||
1788 | op(wtok.bit.siz); |
||
1789 | |||
1790 | wtok.bit.ofs=0; |
||
1791 | |||
1792 | reg2bits(&wtok,r8); |
||
1793 | |||
1794 | op(0x58); //pop eax |
||
1795 | |||
1796 | break; |
||
1797 | |||
1798 | case tk_reg32: |
||
1799 | |||
1800 | if(RegToReg(hnumber,wtok.number,nrazr)==NOINREG){ |
||
1801 | |||
1802 | op(0x89); |
||
1803 | |||
1804 | } |
||
1805 | |||
1806 | } |
||
1807 | |||
1808 | case tk_beg: |
||
1809 | |||
1810 | if(wtok.number!=hnumber){ |
||
1811 | |||
1812 | op(0x88); |
||
1813 | |||
1814 | } |
||
1815 | |||
1816 | } |
||
1817 | |||
1818 | case tk_seg: |
||
1819 | |||
1820 | op(0xC0+wtok.number*8+hnumber); |
||
1821 | |||
1822 | default: |
||
1823 | |||
1824 | } |
||
1825 | |||
1826 | } |
||
1827 | |||
1828 | int do_d_wordvar(int sign,int razr,int terminater) //signed or unsigned 16 or 32 bit memory variable |
||
1829 | |||
1830 | unsigned char next=1,getfromAX=0; |
||
1831 | |||
1832 | ITOK wtok; |
||
1833 | |||
1834 | SINFO wstr; |
||
1835 | |||
1836 | int numpointr=0; |
||
1837 | |||
1838 | int reg1=idxregs[0],reg2=idxregs[1]; |
||
1839 | |||
1840 | int initconst=FALSE; |
||
1841 | |||
1842 | #endif |
||
1843 | |||
1844 | // sign==0?rettype=(razr==r16?tk_word:tk_dword):rettype=(razr==r16?tk_int:tk_long); |
||
1845 | |||
1846 | wstr=strinf; |
||
1847 | |||
1848 | wtok=itok; |
||
1849 | |||
1850 | bufrm=NULL; |
||
1851 | |||
1852 | while(RmEqualReg(hnumber,itok.rm,itok.sib))hnumber++; |
||
1853 | |||
1854 | #ifdef OPTVARCONST |
||
1855 | |||
1856 | #endif |
||
1857 | |||
1858 | case tk_assign: //= |
||
1859 | |||
1860 | ofsstr=GetLecsem(terminater); |
||
1861 | |||
1862 | if(ofsstr){ |
||
1863 | |||
1864 | if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ |
||
1865 | |||
1866 | if(retreg==SKIPREG)retreg=AX; |
||
1867 | |||
1868 | free(ofsstr); |
||
1869 | |||
1870 | if(wstr.bufstr)free(wstr.bufstr); |
||
1871 | |||
1872 | } |
||
1873 | |||
1874 | else tok=tk_reg32; |
||
1875 | |||
1876 | if(reg1==itok.number){ |
||
1877 | |||
1878 | } |
||
1879 | |||
1880 | reg2=idxregs[2]; |
||
1881 | |||
1882 | goto regtovar; |
||
1883 | |||
1884 | } |
||
1885 | |||
1886 | // printf("tok=%d %s\n",tok,itok.name); |
||
1887 | |||
1888 | while(tok==tk_mult){ |
||
1889 | |||
1890 | numpointr++; |
||
1891 | |||
1892 | if(numpointr>itok.npointr){ |
||
1893 | |||
1894 | } |
||
1895 | |||
1896 | hnumber=MultiAssign(razr,USEALLREG,numpointr); |
||
1897 | |||
1898 | free(ofsstr); |
||
1899 | |||
1900 | } |
||
1901 | |||
1902 | goto getfromax; |
||
1903 | |||
1904 | if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr); |
||
1905 | |||
1906 | |||
1907 | |||
1908 | if(tok==tk_number){ //проверка и суммирование чисел |
||
1909 | |||
1910 | next=0; |
||
1911 | |||
1912 | if(postnumflag==0)goto loadconst; |
||
1913 | |||
1914 | } |
||
1915 | |||
1916 | goto labl1; |
||
1917 | |||
1918 | else{ |
||
1919 | |||
1920 | #ifdef OPTVARCONST |
||
1921 | |||
1922 | #endif |
||
1923 | |||
1924 | case tk_number: |
||
1925 | |||
1926 | if((itok.flag&f_reloc)==0){ |
||
1927 | |||
1928 | if(razr==r16)itok.lnumber&=0xffff; |
||
1929 | |||
1930 | if((initconst=Const2Var(&wtok,itok.lnumber,itok.rm))==FALSE){ |
||
1931 | |||
1932 | initconst=TRUE; |
||
1933 | |||
1934 | } |
||
1935 | |||
1936 | if(itok.number==0){ |
||
1937 | |||
1938 | op66(razr); |
||
1939 | |||
1940 | op(0x83); |
||
1941 | |||
1942 | outaddress(&wtok); |
||
1943 | |||
1944 | break; |
||
1945 | |||
1946 | if((razr==r32&&itok.number==0xFFFFFFFF)||(razr==r16&&itok.number==0xFFFF)){ |
||
1947 | |||
1948 | op66(razr); |
||
1949 | |||
1950 | |||
1951 | |||
1952 | outaddress(&wtok); |
||
1953 | |||
1954 | break; |
||
1955 | |||
1956 | if(regoverstack&&razr==r32&&short_ok(itok.number,TRUE)){ |
||
1957 | |||
1958 | op66(razr); |
||
1959 | |||
1960 | op(itok.number); //push short number |
||
1961 | |||
1962 | outseg(&wtok,2); |
||
1963 | |||
1964 | op(wtok.rm); |
||
1965 | |||
1966 | break; |
||
1967 | |||
1968 | } |
||
1969 | |||
1970 | case tk_undefofs: |
||
1971 | |||
1972 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
1973 | |||
1974 | outseg(&wtok,2); |
||
1975 | |||
1976 | op(wtok.rm); |
||
1977 | |||
1978 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
1979 | |||
1980 | else if((itok.flag&f_reloc)!=0)AddReloc(); |
||
1981 | |||
1982 | if(am32!=FALSE&&tok!=tk_number)dwordvalexpected(); |
||
1983 | |||
1984 | } |
||
1985 | |||
1986 | break; |
||
1987 | |||
1988 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
1989 | |||
1990 | outseg(&wtok,2); |
||
1991 | |||
1992 | op(wtok.rm); |
||
1993 | |||
1994 | AddApiToPost(itok.number); |
||
1995 | |||
1996 | case tk_reg32: |
||
1997 | |||
1998 | case tk_reg: |
||
1999 | |||
2000 | regtovar: |
||
2001 | |||
2002 | getfromAX=1; |
||
2003 | |||
2004 | } |
||
2005 | |||
2006 | // if(wbuf==0&&wstr.bufstr==NULL){ |
||
2007 | |||
2008 | AddRegVar(itok.number,razr,&wtok); |
||
2009 | |||
2010 | // } |
||
2011 | |||
2012 | op66(razr); |
||
2013 | |||
2014 | op(0x89); |
||
2015 | |||
2016 | outaddress(&wtok); |
||
2017 | |||
2018 | break; |
||
2019 | |||
2020 | if(razr==r32)goto labl1; |
||
2021 | |||
2022 | op66(r16); |
||
2023 | |||
2024 | op(0x8C); |
||
2025 | |||
2026 | outaddress(&wtok); |
||
2027 | |||
2028 | break; |
||
2029 | |||
2030 | CheckAllMassiv(wbuf,1,&wstr,&wtok); |
||
2031 | |||
2032 | outseg(&wtok,2); |
||
2033 | |||
2034 | op(wtok.rm); |
||
2035 | |||
2036 | if(razr==r16){ |
||
2037 | |||
2038 | outword(addpoststring()); |
||
2039 | |||
2040 | else outdword(addpoststring()); |
||
2041 | |||
2042 | case tk_doublevar: |
||
2043 | |||
2044 | case tk_floatvar: |
||
2045 | |||
2046 | getfromAX=0; |
||
2047 | |||
2048 | outseg(&wtok,2); //fistp var |
||
2049 | |||
2050 | op(wtok.rm+0x18); |
||
2051 | |||
2052 | if(sign==0)warningretsign(); |
||
2053 | |||
2054 | hnumber=EAX; |
||
2055 | |||
2056 | case tk_new: |
||
2057 | |||
2058 | getfromAX=1; |
||
2059 | |||
2060 | #ifdef OPTVARCONST |
||
2061 | |||
2062 | #endif |
||
2063 | |||
2064 | free(ofsstr); |
||
2065 | |||
2066 | } |
||
2067 | |||
2068 | break; |
||
2069 | |||
2070 | dodelete(); |
||
2071 | |||
2072 | getfromAX=1; |
||
2073 | |||
2074 | #ifdef OPTVARCONST |
||
2075 | |||
2076 | #endif |
||
2077 | |||
2078 | hnumber=0; |
||
2079 | |||
2080 | case tk_longvar: |
||
2081 | |||
2082 | if((rettype==tk_long||rettype==tk_dword)&&hnumber&®overstack)goto pushvar; |
||
2083 | |||
2084 | case tk_intvar: |
||
2085 | |||
2086 | if((rettype==tk_int||rettype==tk_word)&&hnumber&®overstack){ |
||
2087 | |||
2088 | CheckAllMassiv(bufrm,razr,&strinf); |
||
2089 | |||
2090 | outseg(&itok,2); |
||
2091 | |||
2092 | op(0x30+itok.rm); |
||
2093 | |||
2094 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2095 | |||
2096 | outseg(&wtok,2); |
||
2097 | |||
2098 | op(wtok.rm); |
||
2099 | |||
2100 | break; |
||
2101 | |||
2102 | goto labl1; |
||
2103 | |||
2104 | labl1: |
||
2105 | |||
2106 | if(rettype==tk_char||rettype==tk_byte){ |
||
2107 | |||
2108 | else{ |
||
2109 | |||
2110 | posiblret=rettype; |
||
2111 | |||
2112 | } |
||
2113 | |||
2114 | if(hnumber==0)retrez=do_e_axmath(sign,r16,&ofsstr); |
||
2115 | |||
2116 | } |
||
2117 | |||
2118 | doeaxfloatmath(tk_fpust,AX,rettype==tk_float?0:4); |
||
2119 | |||
2120 | |||
2121 | |||
2122 | op(razr==r16?0xDF:0xDB); |
||
2123 | |||
2124 | outaddress(&wtok); |
||
2125 | |||
2126 | fwait3(); |
||
2127 | |||
2128 | } |
||
2129 | |||
2130 | if(hnumber==0)retrez=do_e_axmath(sign,r32,&ofsstr); |
||
2131 | |||
2132 | } |
||
2133 | |||
2134 | break; |
||
2135 | |||
2136 | } |
||
2137 | |||
2138 | getfromax: |
||
2139 | |||
2140 | initconst=CheckRegToConst(hnumber,&wtok,razr); |
||
2141 | |||
2142 | if(retrez==0)retrez=razr==r16?tk_reg:tk_reg32; |
||
2143 | |||
2144 | if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP; |
||
2145 | |||
2146 | ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| |
||
2147 | |||
2148 | op66(razr); |
||
2149 | |||
2150 | op(0xA3); // MOV [word],AX |
||
2151 | |||
2152 | AddUndefOff(2,wtok.name); |
||
2153 | |||
2154 | } |
||
2155 | |||
2156 | else outdword(wtok.number); |
||
2157 | |||
2158 | else{ |
||
2159 | |||
2160 | // printf("flag=%08X rm=%d num=%d post=%d sib=%d\n",wtok.flag,wtok.rm,wtok.number,wtok.post,wtok.sib); |
||
2161 | |||
2162 | outseg(&wtok,2); |
||
2163 | |||
2164 | outaddress(&wtok); |
||
2165 | |||
2166 | if(ofsstr)IDZToReg(ofsstr,hnumber,razr); |
||
2167 | |||
2168 | KillVar(wtok.name); |
||
2169 | |||
2170 | } |
||
2171 | |||
2172 | // printf("vop=%d %s\n",vop,wtok.name); |
||
2173 | |||
2174 | } |
||
2175 | |||
2176 | break; |
||
2177 | |||
2178 | case tk_plusplus: |
||
2179 | |||
2180 | initconst=UpdVarConst(&wtok,1,tk_byte,tok); |
||
2181 | |||
2182 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2183 | |||
2184 | outseg(&wtok,2); |
||
2185 | |||
2186 | outaddress(&wtok); |
||
2187 | |||
2188 | break; |
||
2189 | |||
2190 | case tk_pascal: |
||
2191 | |||
2192 | case tk_stdcall: |
||
2193 | |||
2194 | nexttok(); |
||
2195 | |||
2196 | expected('('); |
||
2197 | |||
2198 | } |
||
2199 | |||
2200 | param[0]=0; |
||
2201 | |||
2202 | i=0; |
||
2203 | |||
2204 | case tk_cdecl: |
||
2205 | |||
2206 | i=swapparam(); |
||
2207 | |||
2208 | case tk_pascal: |
||
2209 | |||
2210 | break; |
||
2211 | |||
2212 | doregparams(); |
||
2213 | |||
2214 | default: |
||
2215 | |||
2216 | else doparams(); |
||
2217 | |||
2218 | if(vop!=tk_cdecl)i=0; |
||
2219 | |||
2220 | outseg(&wtok,2); |
||
2221 | |||
2222 | outaddress(&wtok); |
||
2223 | |||
2224 | #ifdef OPTVARCONST |
||
2225 | |||
2226 | #endif |
||
2227 | |||
2228 | break; |
||
2229 | |||
2230 | case tk_minusequals: vop+=0x08; |
||
2231 | |||
2232 | case tk_orequals: vop+=0x08; |
||
2233 | |||
2234 | getoperand(am32==TRUE?EAX:BX); |
||
2235 | |||
2236 | getoperand(am32==TRUE?EAX:BX); |
||
2237 | |||
2238 | goto axtovar; |
||
2239 | |||
2240 | if(itok2.type==tp_opperand){ |
||
2241 | |||
2242 | if(OnlyNumber(sign)){ |
||
2243 | |||
2244 | otok=tok; |
||
2245 | |||
2246 | goto num; |
||
2247 | |||
2248 | } |
||
2249 | |||
2250 | do_e_axmath(sign,razr,&ofsstr); |
||
2251 | |||
2252 | axtovar: |
||
2253 | |||
2254 | |||
2255 | |||
2256 | op(0x01+vop); op(wtok.rm); /* ADD [anyword],AX */ |
||
2257 | |||
2258 | next=0; |
||
2259 | |||
2260 | else{ |
||
2261 | |||
2262 | case tk_number: |
||
2263 | |||
2264 | case tk_undefofs: |
||
2265 | |||
2266 | #ifdef OPTVARCONST |
||
2267 | |||
2268 | initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand); |
||
2269 | |||
2270 | #endif |
||
2271 | |||
2272 | op66(razr); |
||
2273 | |||
2274 | if(tok==tk_number&&(itok.flag&f_reloc)==0&&itok.number==1&&(vop==0||vop==0x28)){ |
||
2275 | |||
2276 | op(0xFF); op(vop+wtok.rm); |
||
2277 | |||
2278 | } |
||
2279 | |||
2280 | short_ok(itok.number,razr/2-1)){ |
||
2281 | |||
2282 | op(vop+wtok.rm); |
||
2283 | |||
2284 | op((unsigned int)itok.number); |
||
2285 | |||
2286 | else{ |
||
2287 | |||
2288 | op(vop+wtok.rm); |
||
2289 | |||
2290 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
2291 | |||
2292 | else if((itok.flag&f_reloc)!=0)AddReloc(); |
||
2293 | |||
2294 | } |
||
2295 | |||
2296 | break; |
||
2297 | |||
2298 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2299 | |||
2300 | outseg(&wtok,2); |
||
2301 | |||
2302 | op(vop+wtok.rm); |
||
2303 | |||
2304 | AddApiToPost(itok.number); |
||
2305 | |||
2306 | case tk_reg32: |
||
2307 | |||
2308 | case tk_reg: |
||
2309 | |||
2310 | #ifdef OPTVARCONST |
||
2311 | |||
2312 | #endif |
||
2313 | |||
2314 | op66(razr); |
||
2315 | |||
2316 | op(0x01+vop); op((unsigned int)itok.number*8+wtok.rm); |
||
2317 | |||
2318 | break; |
||
2319 | |||
2320 | defxor: |
||
2321 | |||
2322 | do_e_axmath(sign,razr,&ofsstr); |
||
2323 | |||
2324 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2325 | |||
2326 | outseg(&wtok,2); |
||
2327 | |||
2328 | outaddress(&wtok); |
||
2329 | |||
2330 | break; |
||
2331 | |||
2332 | } |
||
2333 | |||
2334 | KillVar(wtok.name); |
||
2335 | |||
2336 | case tk_multequals: |
||
2337 | |||
2338 | if(itok2.type==tp_stopper){ |
||
2339 | |||
2340 | if(itok.number==1)break; |
||
2341 | |||
2342 | ZeroReg(hnumber,razr); |
||
2343 | |||
2344 | } |
||
2345 | |||
2346 | if((itok.flag&f_reloc)==0){ |
||
2347 | |||
2348 | } |
||
2349 | |||
2350 | if(hnumber==0)getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE); |
||
2351 | |||
2352 | vop=0; |
||
2353 | |||
2354 | goto getfromax; |
||
2355 | |||
2356 | } |
||
2357 | |||
2358 | else getintoreg(hnumber,razr,sign,&ofsstr); |
||
2359 | |||
2360 | wtok.number+=addESP-oaddESP; |
||
2361 | |||
2362 | } |
||
2363 | |||
2364 | op66(razr); |
||
2365 | |||
2366 | outseg(&wtok,2); |
||
2367 | |||
2368 | if(sign)op(0x28+wtok.rm); |
||
2369 | |||
2370 | } |
||
2371 | |||
2372 | outseg(&wtok,3); |
||
2373 | |||
2374 | op(wtok.rm+hnumber*8); |
||
2375 | |||
2376 | outaddress(&wtok); |
||
2377 | |||
2378 | KillVar(wtok.name); |
||
2379 | |||
2380 | case tk_divequals: |
||
2381 | |||
2382 | hnumber=0; |
||
2383 | |||
2384 | if(tok==tk_number){ |
||
2385 | |||
2386 | #ifdef OPTVARCONST |
||
2387 | |||
2388 | initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand); |
||
2389 | |||
2390 | #endif |
||
2391 | |||
2392 | DivMod(0,sign,razr,0); |
||
2393 | |||
2394 | goto getfromax; |
||
2395 | |||
2396 | getintoreg_32(CX,razr,sign,&ofsstr); |
||
2397 | |||
2398 | else{ |
||
2399 | |||
2400 | if(optimizespeed)outword(0xC88B); //mov CX,ax |
||
2401 | |||
2402 | if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar)){ |
||
2403 | |||
2404 | oaddESP=addESP; |
||
2405 | |||
2406 | } |
||
2407 | |||
2408 | ClearDX(razr,sign); |
||
2409 | |||
2410 | op(0xF7); |
||
2411 | |||
2412 | else op(0xF0+ECX); // DIV CX |
||
2413 | |||
2414 | warningreg(regs[razr/2-1][ECX]); |
||
2415 | |||
2416 | goto getfromax; |
||
2417 | |||
2418 | KillVar(wtok.name); |
||
2419 | |||
2420 | regdi=TRUE; |
||
2421 | |||
2422 | rbuf=bufrm; |
||
2423 | |||
2424 | if(am32!=FALSE&&wbuf!=NULL&&wstr.bufstr!=NULL)regdi=FALSE; |
||
2425 | |||
2426 | case tk_reg32: |
||
2427 | |||
2428 | case tk_reg: |
||
2429 | |||
2430 | #ifdef OPTVARCONST |
||
2431 | |||
2432 | #endif |
||
2433 | |||
2434 | op66(razr); |
||
2435 | |||
2436 | op(0x87); |
||
2437 | |||
2438 | outaddress(&wtok); |
||
2439 | |||
2440 | break; |
||
2441 | |||
2442 | case tk_longvar: |
||
2443 | |||
2444 | if(razr==r16)swaperror(); |
||
2445 | |||
2446 | case tk_wordvar: |
||
2447 | |||
2448 | #ifdef OPTVARCONST |
||
2449 | |||
2450 | #endif |
||
2451 | |||
2452 | else{ |
||
2453 | |||
2454 | CheckAllMassiv(bufrm,razr,&strinf); |
||
2455 | |||
2456 | outseg(&itok,2); |
||
2457 | |||
2458 | op(0x30+itok.rm); |
||
2459 | |||
2460 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2461 | |||
2462 | outseg(&wtok,2); |
||
2463 | |||
2464 | op(0x30+wtok.rm); |
||
2465 | |||
2466 | |||
2467 | |||
2468 | op66(razr); |
||
2469 | |||
2470 | op(0x8f); |
||
2471 | |||
2472 | outaddress(&itok); |
||
2473 | |||
2474 | op66(razr); |
||
2475 | |||
2476 | op(0x8f); |
||
2477 | |||
2478 | outaddress(&wtok); |
||
2479 | |||
2480 | break; |
||
2481 | |||
2482 | getinto_reg(otok,&wtok,wbuf,&wstr,razr,hnumber); |
||
2483 | |||
2484 | CheckAllMassiv(rbuf,razr,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
2485 | |||
2486 | outseg(&itok,2); |
||
2487 | |||
2488 | op(itok.rm+hnumber*8); |
||
2489 | |||
2490 | goto getfromax; |
||
2491 | |||
2492 | if(razr==r32)swaperror(); |
||
2493 | |||
2494 | op(0x8C); /* MOV AX,seg */ |
||
2495 | |||
2496 | CheckAllMassiv(wbuf,2,&wstr,&wtok); |
||
2497 | |||
2498 | outseg(&wtok,2); |
||
2499 | |||
2500 | op(wtok.rm); |
||
2501 | |||
2502 | |||
2503 | |||
2504 | op(0xC0+(unsigned int)itok.number*8); |
||
2505 | |||
2506 | case tk_floatvar: |
||
2507 | |||
2508 | if(sign==1){ |
||
2509 | |||
2510 | outseg(&wtok,2); //fild |
||
2511 | |||
2512 | op(wtok.rm); |
||
2513 | |||
2514 | CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
2515 | |||
2516 | op(0xd9); |
||
2517 | |||
2518 | outaddress(&itok); |
||
2519 | |||
2520 | else{ |
||
2521 | |||
2522 | op66(r32); //push 0L |
||
2523 | |||
2524 | CheckAllMassiv(wbuf,4,&wstr,&wtok); |
||
2525 | |||
2526 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; |
||
2527 | |||
2528 | outseg(&wtok,2); |
||
2529 | |||
2530 | op(wtok.rm+0x30); |
||
2531 | |||
2532 | fildq_stack(); |
||
2533 | |||
2534 | outseg(&itok,2); //fld val |
||
2535 | |||
2536 | op(itok.rm); |
||
2537 | |||
2538 | RestoreBP(); |
||
2539 | |||
2540 | outword(0xC483); |
||
2541 | |||
2542 | } |
||
2543 | |||
2544 | op(0x58); // pop EAX |
||
2545 | |||
2546 | } |
||
2547 | |||
2548 | } |
||
2549 | |||
2550 | |||
2551 | |||
2552 | outaddress(&wtok); |
||
2553 | |||
2554 | op(0xd9); |
||
2555 | |||
2556 | outaddress(&itok); |
||
2557 | |||
2558 | break; |
||
2559 | |||
2560 | } |
||
2561 | |||
2562 | case tk_rrequals: |
||
2563 | |||
2564 | if(sign)vop+=0x10; |
||
2565 | |||
2566 | KillVar(wtok.name); |
||
2567 | |||
2568 | if(itok2.type!=tp_stopper){ |
||
2569 | |||
2570 | ClearReg(AX); |
||
2571 | |||
2572 | outword(0xC188); // MOV CL,AL |
||
2573 | |||
2574 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2575 | |||
2576 | outseg(&wtok,2); |
||
2577 | |||
2578 | outaddress(&wtok); |
||
2579 | |||
2580 | next=0; |
||
2581 | |||
2582 | else if(tok==tk_number){ |
||
2583 | |||
2584 | if((itok.flag&f_reloc)==0){ |
||
2585 | |||
2586 | } |
||
2587 | |||
2588 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
2589 | |||
2590 | op66(razr); |
||
2591 | |||
2592 | op(0xD1); op(0x20+vop+wtok.rm); /* SHL [rmword],1 */ |
||
2593 | |||
2594 | } |
||
2595 | |||
2596 | if(chip<2&&razr==r16){ |
||
2597 | |||
2598 | op66(r16); |
||
2599 | |||
2600 | op(0xD3); op(0x20+vop+wtok.rm); /* SHL [rmword],CL */ |
||
2601 | |||
2602 | warningreg(begs[1]); |
||
2603 | |||
2604 | next=0; |
||
2605 | |||
2606 | else{ |
||
2607 | |||
2608 | outseg(&wtok,2); |
||
2609 | |||
2610 | outaddress(&wtok); |
||
2611 | |||
2612 | } |
||
2613 | |||
2614 | } |
||
2615 | |||
2616 | else{ |
||
2617 | |||
2618 | getintobeg(CL,&ofsstr); |
||
2619 | |||
2620 | ClearReg(CX); |
||
2621 | |||
2622 | } |
||
2623 | |||
2624 | op66(razr); |
||
2625 | |||
2626 | op(0xD3); op(0x20+vop+wtok.rm); /* SHL [rmword],CL */ |
||
2627 | |||
2628 | } |
||
2629 | |||
2630 | default: operatorexpected(); break; |
||
2631 | |||
2632 | #ifdef OPTVARCONST |
||
2633 | |||
2634 | #endif |
||
2635 | |||
2636 | if(terminater==tk_semicolon)seminext(); |
||
2637 | |||
2638 | return retrez; |
||
2639 | |||
2640 | |||
2641 | |||
2642 | { |
||
2643 | |||
2644 | unsigned int vop=0,otok,rettype,posiblret; |
||
2645 | |||
2646 | char *bbuf,*rbuf; |
||
2647 | |||
2648 | SINFO bstr; |
||
2649 | |||
2650 | char *ofsstr=NULL; |
||
2651 | |||
2652 | int initconst=FALSE; |
||
2653 | |||
2654 | #endif |
||
2655 | |||
2656 | sign==0?posiblret=rettype=tk_byte:posiblret=rettype=tk_char; |
||
2657 | |||
2658 | strinf.bufstr=NULL; |
||
2659 | |||
2660 | bbuf=bufrm; |
||
2661 | |||
2662 | otok=tok; |
||
2663 | |||
2664 | nexttok(); |
||
2665 | |||
2666 | operand=tok; |
||
2667 | |||
2668 | switch(tok){ |
||
2669 | |||
2670 | if(!((tok2==tk_reg||tok2==tk_reg32||tok2==tk_beg)&&ScanTok3()==terminater)){ |
||
2671 | |||
2672 | } |
||
2673 | |||
2674 | int retreg; |
||
2675 | |||
2676 | GetEndLex(terminater); |
||
2677 | |||
2678 | itok.number=retreg==SKIPREG?AX:retreg; |
||
2679 | |||
2680 | } |
||
2681 | |||
2682 | nexttok(); |
||
2683 | |||
2684 | while(tok==tk_mult){ |
||
2685 | |||
2686 | numpointr++; |
||
2687 | |||
2688 | if(numpointr>itok.npointr)unuseableinput(); |
||
2689 | |||
2690 | hnumber=MultiAssign(r8,USEALLREG,numpointr); |
||
2691 | |||
2692 | free(ofsstr); |
||
2693 | |||
2694 | } |
||
2695 | |||
2696 | goto getfromax; |
||
2697 | |||
2698 | if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr); |
||
2699 | |||
2700 | if(itok2.type==tp_opperand){ |
||
2701 | |||
2702 | if(OnlyNumber(sign)){ |
||
2703 | |||
2704 | goto numbertovar; |
||
2705 | |||
2706 | } |
||
2707 | |||
2708 | } |
||
2709 | |||
2710 | #ifdef OPTVARCONST |
||
2711 | |||
2712 | if(CheckConstVar(&itok))tok=tk_number; |
||
2713 | |||
2714 | #endif |
||
2715 | |||
2716 | case tk_number: |
||
2717 | |||
2718 | #ifdef OPTVARCONST |
||
2719 | |||
2720 | waralreadinitvar(btok.name,itok.number); |
||
2721 | |||
2722 | break; |
||
2723 | |||
2724 | #endif |
||
2725 | |||
2726 | outseg(&btok,2); |
||
2727 | |||
2728 | op(btok.rm); |
||
2729 | |||
2730 | op((unsigned int)itok.number); |
||
2731 | |||
2732 | case tk_reg32: |
||
2733 | |||
2734 | if((unsigned int)itok.number>BX)goto labl1; |
||
2735 | |||
2736 | regtovar: |
||
2737 | |||
2738 | getfromAX=1; |
||
2739 | |||
2740 | } |
||
2741 | |||
2742 | KillVar(btok.name); |
||
2743 | |||
2744 | vop++; |
||
2745 | |||
2746 | outseg(&btok,2); |
||
2747 | |||
2748 | op((unsigned int)itok.number*8+btok.rm); |
||
2749 | |||
2750 | } |
||
2751 | |||
2752 | case tk_seg: segbyteerror(); break; |
||
2753 | |||
2754 | labl1: |
||
2755 | |||
2756 | if(hnumber==0)retrez=doalmath(sign,&ofsstr); |
||
2757 | |||
2758 | } |
||
2759 | |||
2760 | if(hnumber==0)retrez=do_e_axmath(sign,r16,&ofsstr); |
||
2761 | |||
2762 | } |
||
2763 | |||
2764 | doeaxfloatmath(tk_reg32); |
||
2765 | |||
2766 | hnumber=0; |
||
2767 | |||
2768 | else{ |
||
2769 | |||
2770 | else retrez=getintoreg(hnumber,r32,sign,&ofsstr); |
||
2771 | |||
2772 | getfromAX=1; |
||
2773 | |||
2774 | break; |
||
2775 | |||
2776 | } |
||
2777 | |||
2778 | getfromax: |
||
2779 | |||
2780 | initconst=CheckRegToConst(hnumber,&btok,r8); |
||
2781 | |||
2782 | if(retrez==0)retrez=tk_reg; |
||
2783 | |||
2784 | if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar))btok.number+=addESP-oaddESP; |
||
2785 | |||
2786 | outseg(&btok,1); |
||
2787 | |||
2788 | if(btok.post==UNDEF_OFSET){ |
||
2789 | |||
2790 | btok.post=0; |
||
2791 | |||
2792 | if(am32==FALSE)outword(btok.number); |
||
2793 | |||
2794 | } |
||
2795 | |||
2796 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2797 | |||
2798 | op(0x88); |
||
2799 | |||
2800 | outaddress(&btok); |
||
2801 | |||
2802 | if(ofsstr)IDZToReg(ofsstr,hnumber,r8); |
||
2803 | |||
2804 | KillVar(btok.name); |
||
2805 | |||
2806 | } |
||
2807 | |||
2808 | if(ofsstr)free(ofsstr); |
||
2809 | |||
2810 | case tk_multequals: |
||
2811 | |||
2812 | if(itok2.type==tp_stopper&&tok==tk_number){ |
||
2813 | |||
2814 | if(itok.number==0){ |
||
2815 | |||
2816 | goto getfromax; |
||
2817 | |||
2818 | #ifdef OPTVARCONST |
||
2819 | |||
2820 | initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,tk_mult); |
||
2821 | |||
2822 | #endif |
||
2823 | |||
2824 | doalmath(sign,&ofsstr); |
||
2825 | |||
2826 | if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar)){ |
||
2827 | |||
2828 | oaddESP=addESP; |
||
2829 | |||
2830 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2831 | |||
2832 | op(0xF6); |
||
2833 | |||
2834 | else op(0x20+btok.rm); |
||
2835 | |||
2836 | next=0; |
||
2837 | |||
2838 | goto getfromax; |
||
2839 | |||
2840 | hnumber=0; |
||
2841 | |||
2842 | if(itok2.type==tp_stopper){ |
||
2843 | |||
2844 | if(itok.number==1)break; |
||
2845 | |||
2846 | if((itok.flag&f_reloc)==0){ |
||
2847 | |||
2848 | } |
||
2849 | |||
2850 | } |
||
2851 | |||
2852 | |||
2853 | |||
2854 | else{ |
||
2855 | |||
2856 | |||
2857 | |||
2858 | btok.number+=addESP-oaddESP; |
||
2859 | |||
2860 | } |
||
2861 | |||
2862 | if(sign)cbw(); |
||
2863 | |||
2864 | getintoal(otok,&btok,bbuf,&bstr); |
||
2865 | |||
2866 | op(0xF6); |
||
2867 | |||
2868 | else op(0xF0+CL); // DIV CL |
||
2869 | |||
2870 | ClearReg(CX); |
||
2871 | |||
2872 | goto getfromax; |
||
2873 | |||
2874 | case tk_plusplus: |
||
2875 | |||
2876 | initconst=UpdVarConst(&btok,1,tk_byte,tok); |
||
2877 | |||
2878 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2879 | |||
2880 | op(0xFE); |
||
2881 | |||
2882 | outaddress(&btok); |
||
2883 | |||
2884 | break; |
||
2885 | |||
2886 | case tk_minusequals: vop+=0x08; |
||
2887 | |||
2888 | case tk_orequals: vop+=0x08; |
||
2889 | |||
2890 | KillVar(btok.name); |
||
2891 | |||
2892 | if(itok2.type==tp_opperand){ |
||
2893 | |||
2894 | if(OnlyNumber(sign)){ |
||
2895 | |||
2896 | otok=tok; |
||
2897 | |||
2898 | goto num; |
||
2899 | |||
2900 | } |
||
2901 | |||
2902 | |||
2903 | |||
2904 | outseg(&btok,2); |
||
2905 | |||
2906 | outaddress(&btok); |
||
2907 | |||
2908 | retrez=tk_reg; |
||
2909 | |||
2910 | else{ |
||
2911 | |||
2912 | case tk_number: |
||
2913 | |||
2914 | #ifdef OPTVARCONST |
||
2915 | |||
2916 | initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,operand); |
||
2917 | |||
2918 | #endif |
||
2919 | |||
2920 | outseg(&btok,2); |
||
2921 | |||
2922 | if(vop)vop=8; |
||
2923 | |||
2924 | op(vop+btok.rm); |
||
2925 | |||
2926 | } |
||
2927 | |||
2928 | op(0x80); |
||
2929 | |||
2930 | outaddress(&btok); |
||
2931 | |||
2932 | } |
||
2933 | |||
2934 | break; |
||
2935 | |||
2936 | #ifdef OPTVARCONST |
||
2937 | |||
2938 | #endif |
||
2939 | |||
2940 | outseg(&btok,2); |
||
2941 | |||
2942 | op((unsigned int)itok.number*8+btok.rm); |
||
2943 | |||
2944 | break; |
||
2945 | |||
2946 | default: |
||
2947 | |||
2948 | doalmath(sign,&ofsstr); |
||
2949 | |||
2950 | outseg(&btok,2); |
||
2951 | |||
2952 | outaddress(&btok); |
||
2953 | |||
2954 | break; |
||
2955 | |||
2956 | } |
||
2957 | |||
2958 | case tk_swap: |
||
2959 | |||
2960 | getoperand(); |
||
2961 | |||
2962 | bufrm=NULL; |
||
2963 | |||
2964 | case tk_beg: |
||
2965 | |||
2966 | |||
2967 | |||
2968 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
2969 | |||
2970 | op(0x86); /* XCHG beg,[anybloc] */ |
||
2971 | |||
2972 | outaddress(&btok); |
||
2973 | |||
2974 | break; |
||
2975 | |||
2976 | case tk_charvar: |
||
2977 | |||
2978 | initconst=SwapVarConst(&itok,&btok); |
||
2979 | |||
2980 | if(hnumber==0)getintoal(otok,&btok,bbuf,&bstr); |
||
2981 | |||
2982 | CheckAllMassiv(rbuf,1,&strinf,&itok,(am32!=FALSE&&bbuf!=NULL&&bstr.bufstr!=NULL)?BX:DI,DX); |
||
2983 | |||
2984 | op(0x86); /* XCHG AL,[bloc] */ |
||
2985 | |||
2986 | outaddress(&itok); |
||
2987 | |||
2988 | goto getfromax; |
||
2989 | |||
2990 | } |
||
2991 | |||
2992 | case tk_rrequals: |
||
2993 | |||
2994 | if(sign)vop+=0x10; |
||
2995 | |||
2996 | KillVar(btok.name); |
||
2997 | |||
2998 | if(itok2.type!=tp_stopper){ |
||
2999 | |||
3000 | outword(0xC188); // MOV CL,AL |
||
3001 | |||
3002 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
3003 | |||
3004 | op(0xD2); op(0x20+vop+btok.rm); /* SHL [byte],CL */ |
||
3005 | |||
3006 | warningreg(begs[1]); |
||
3007 | |||
3008 | ClearReg(AX); |
||
3009 | |||
3010 | } |
||
3011 | |||
3012 | #ifdef OPTVARCONST |
||
3013 | |||
3014 | initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,operand); |
||
3015 | |||
3016 | #endif |
||
3017 | |||
3018 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
3019 | |||
3020 | op(0xD0); op(0x20+vop+btok.rm); /* SHL [byte],1 */ |
||
3021 | |||
3022 | } |
||
3023 | |||
3024 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
3025 | |||
3026 | getintobeg(CL,&ofsstr); |
||
3027 | |||
3028 | op(0xD2); op(0x20+vop+btok.rm); /* SHL [byte],CL */ |
||
3029 | |||
3030 | warningreg(begs[1]); |
||
3031 | |||
3032 | next=0; |
||
3033 | |||
3034 | else{ |
||
3035 | |||
3036 | op(0xC0); op(0x20+vop+btok.rm); /* SHL [byte],imm8 */ |
||
3037 | |||
3038 | if(cpu<2)cpu=2; |
||
3039 | |||
3040 | op((unsigned int)itok.number); |
||
3041 | |||
3042 | } |
||
3043 | |||
3044 | if(tok!=tk_beg||(unsigned int)itok.number!=CL){ |
||
3045 | |||
3046 | warningreg(begs[1]); |
||
3047 | |||
3048 | next=0; |
||
3049 | |||
3050 | CheckAllMassiv(bbuf,1,&bstr,&btok); |
||
3051 | |||
3052 | op(0xD2); op(0x20+vop+btok.rm); /* SHL [byte],CL */ |
||
3053 | |||
3054 | } |
||
3055 | |||
3056 | default: operatorexpected(); break; |
||
3057 | |||
3058 | #ifdef OPTVARCONST |
||
3059 | |||
3060 | #endif |
||
3061 | |||
3062 | if(terminater==tk_semicolon)seminext(); |
||
3063 | |||
3064 | } |
||
3065 | |||
3066 | void getinto_reg(int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr,int razr,int reg) |
||
3067 | |||
3068 | unsigned int i=0; |
||
3069 | |||
3070 | int reg1=SI,reg2=DI; |
||
3071 | |||
3072 | case tk_dwordvar: |
||
3073 | |||
3074 | i+=4; |
||
3075 | |||
3076 | CheckAllMassiv(gbuf,i,gstr,gstok,reg1,reg2); |
||
3077 | |||
3078 | outseg(gstok,2); |
||
3079 | |||
3080 | op(gstok->rm+reg*8); |
||
3081 | |||
3082 | ClearReg(reg); |
||
3083 | |||
3084 | case tk_intvar: |
||
3085 | |||
3086 | case tk_wordvar: |
||
3087 | |||
3088 | goto longvar; |
||
3089 | |||
3090 | case tk_charvar: |
||
3091 | |||
3092 | outseg(gstok,2); |
||
3093 | |||
3094 | op(gstok->rm+reg*8); |
||
3095 | |||
3096 | ClearReg(reg); |
||
3097 | |||
3098 | } |
||
3099 | |||
3100 | |||
3101 | |||
3102 | { |
||
3103 | |||
3104 | int vop=0; |
||
3105 | |||
3106 | if(am32){ |
||
3107 | |||
3108 | reg2=idxregs[3]; |
||
3109 | |||
3110 | // printf("tok=%u %s\n",gtok,gstok->name); |
||
3111 | |||
3112 | case tk_bits: |
||
3113 | |||
3114 | if(vop<=64)i=r64; |
||
3115 | |||
3116 | if(vop<=16)i=r16; |
||
3117 | |||
3118 | break; |
||
3119 | |||
3120 | op66(razr); |
||
3121 | |||
3122 | (gstok->flag&f_extern)==0?setwordpost(gstok):setwordext(&gstok->number); |
||
3123 | |||
3124 | ClearReg(AX); |
||
3125 | |||
3126 | case tk_rmnumber: |
||
3127 | |||
3128 | if(gstok->rm||am32==0){ |
||
3129 | |||
3130 | op67(gstok->sib==CODE16?r16:r32); |
||
3131 | |||
3132 | op(0x8D); op(gstok->rm); |
||
3133 | |||
3134 | if((gstok->flag&f_extern)==0){ |
||
3135 | |||
3136 | if(am32&&gstok->rm==rm_sib)outptr++; |
||
3137 | |||
3138 | outptr=i; |
||
3139 | |||
3140 | else setwordext(&gstok->number); |
||
3141 | |||
3142 | outaddress(gstok); /* LEA AX,[rm] */ |
||
3143 | |||
3144 | } |
||
3145 | |||
3146 | break; |
||
3147 | |||
3148 | vop=4; |
||
3149 | |||
3150 | CheckInitBP(); |
||
3151 | |||
3152 | op66(r32); |
||
3153 | |||
3154 | if(ESPloc&&am32&&gstok->segm==SS)gstok->number+=4; |
||
3155 | |||
3156 | CheckAllMassiv(gbuf,4,gstr,gstok,reg1,reg2); |
||
3157 | |||
3158 | op(0xd9+vop); |
||
3159 | |||
3160 | outaddress(gstok); |
||
3161 | |||
3162 | op66(r32); |
||
3163 | |||
3164 | addESP-=4; |
||
3165 | |||
3166 | ClearReg(AX); |
||
3167 | |||
3168 | case tk_qwordvar: |
||
3169 | |||
3170 | case tk_dwordvar: |
||
3171 | |||
3172 | i+=4; |
||
3173 | |||
3174 | if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){ |
||
3175 | |||
3176 | outseg(gstok,1); |
||
3177 | |||
3178 | if(gstok->post==UNDEF_OFSET)AddUndefOff(2,gstok->name); |
||
3179 | |||
3180 | else outdword(gstok->number); |
||
3181 | |||
3182 | else{ |
||
3183 | |||
3184 | op66(razr); |
||
3185 | |||
3186 | op(0x8B); |
||
3187 | |||
3188 | outaddress(gstok); |
||
3189 | |||
3190 | ClearReg(AX); |
||
3191 | |||
3192 | case tk_intvar: |
||
3193 | |||
3194 | case tk_wordvar: |
||
3195 | |||
3196 | if(razr==r16)goto longvar; |
||
3197 | |||
3198 | if(optimizespeed&&vop==0&&chip>3&&chip<7)goto optpent; |
||
3199 | |||
3200 | CheckAllMassiv(gbuf,1+i,gstr,gstok,reg1,reg2); |
||
3201 | |||
3202 | outseg(gstok,3); /* MOVSX EAX,[charvar] */ |
||
3203 | |||
3204 | outaddress(gstok); |
||
3205 | |||
3206 | break; |
||
3207 | |||
3208 | vop=8; |
||
3209 | |||
3210 | if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){ |
||
3211 | |||
3212 | op(0xA0); |
||
3213 | |||
3214 | else outdword(gstok->number); |
||
3215 | |||
3216 | else{ |
||
3217 | |||
3218 | outseg(gstok,2); |
||
3219 | |||
3220 | outaddress(gstok); |
||
3221 | |||
3222 | cbw(); |
||
3223 | |||
3224 | break; |
||
3225 | |||
3226 | goto movxx; |
||
3227 | |||
3228 | optpent: |
||
3229 | |||
3230 | ZeroReg(EAX,razr); |
||
3231 | |||
3232 | outseg(gstok,1); |
||
3233 | |||
3234 | if(am32==FALSE)outword(gstok->number); |
||
3235 | |||
3236 | ClearReg(AX); |
||
3237 | |||
3238 | } |
||
3239 | |||
3240 | ZeroReg(EAX,razr); |
||
3241 | |||
3242 | if(i)op66(r16); |
||
3243 | |||
3244 | op(0x8A+i); op(gstok->rm); |
||
3245 | |||
3246 | break; |
||
3247 | |||
3248 | if(gstok->number==AL&&(!sign)&&razr==r16){ |
||
3249 | |||
3250 | ClearReg(AX); |
||
3251 | |||
3252 | } |
||
3253 | |||
3254 | if(sign){ |
||
3255 | |||
3256 | if(gstok->number!=AL){ |
||
3257 | |||
3258 | op(0xC0+gstok->number*8); //mov al,beg |
||
3259 | |||
3260 | if(gstok->number!=AH)outword(0xC488); //mov ah,al |
||
3261 | |||
3262 | op(7); |
||
3263 | |||
3264 | else{ |
||
3265 | |||
3266 | /*if(chip==4)*/goto movxxr; |
||
3267 | |||
3268 | op(0xC1+gstok->number*8); //mov cl,beg |
||
3269 | |||
3270 | outword(0xC888); // mov al,cl |
||
3271 | |||
3272 | break;*/ |
||
3273 | |||
3274 | if(gstok->number==AH)outdword(0xE430E088); //mov al,ah xor ah,ah |
||
3275 | |||
3276 | ZeroReg(EAX,razr); |
||
3277 | |||
3278 | op(0xC0+gstok->number*8); //mov al,beg |
||
3279 | |||
3280 | } |
||
3281 | |||
3282 | break; |
||
3283 | |||
3284 | movxxr: |
||
3285 | |||
3286 | op66(razr); |
||
3287 | |||
3288 | else outword(0xB60F); |
||
3289 | |||
3290 | } |
||
3291 | |||
3292 | op(0x88); |
||
3293 | |||
3294 | if(sign)cbw(); |
||
3295 | |||
3296 | } |
||
3297 | |||
3298 | break; |
||
3299 | |||
3300 | if(razr==r32){ |
||
3301 | |||
3302 | reg1=gstok->number; |
||
3303 | |||
3304 | param[0]=0; |
||
3305 | |||
3306 | else doparams(); |
||
3307 | |||
3308 | op(0xFF); |
||
3309 | |||
3310 | #ifdef OPTVARCONST |
||
3311 | |||
3312 | #endif |
||
3313 | |||
3314 | break; |
||
3315 | |||
3316 | if(optimizespeed&&(!sign)&&chip>3&&chip<7){ |
||
3317 | |||
3318 | goto movxr; |
||
3319 | |||
3320 | outword(0xC189); //mov cx,AX |
||
3321 | |||
3322 | op66(r16); |
||
3323 | |||
3324 | warningreg(regs[0][1]);*/ |
||
3325 | |||
3326 | else{ |
||
3327 | |||
3328 | op66(r16); |
||
3329 | |||
3330 | op(0xC0+gstok->number*8); //mov ax,reg |
||
3331 | |||
3332 | } |
||
3333 | |||
3334 | movxr: |
||
3335 | |||
3336 | op(0x0F); /* MOVSX or MOVZX EAX,reg */ |
||
3337 | |||
3338 | else op(0xB7); |
||
3339 | |||
3340 | } |
||
3341 | |||
3342 | break; |
||
3343 | |||
3344 | case tk_reg32: |
||
3345 | |||
3346 | reg1=gstok->number; |
||
3347 | |||
3348 | param[0]=0; |
||
3349 | |||
3350 | else doparams(); |
||
3351 | |||
3352 | op(0xFF); |
||
3353 | |||
3354 | clearregstat(); |
||
3355 | |||
3356 | FreeGlobalConst(); |
||
3357 | |||
3358 | break; |
||
3359 | |||
3360 | if(gstok->number!=AX){ |
||
3361 | |||
3362 | op(0x89); |
||
3363 | |||
3364 | RegToReg(AX,gstok->number,razr); |
||
3365 | |||
3366 | break; |
||
3367 | |||
3368 | if(razr==r32)op66(r32); |
||
3369 | |||
3370 | op(0xC0+gstok->number*8); |
||
3371 | |||
3372 | break; |
||
3373 | |||
3374 | op66(razr); |
||
3375 | |||
3376 | if(razr==r16){ |
||
3377 | |||
3378 | outword(addpoststring(CS,gstok->number,gstok->flag)); |
||
3379 | |||
3380 | else outdword(addpoststring(CS,gstok->number,gstok->flag)); |
||
3381 | |||
3382 | break; |
||
3383 | |||
3384 | } |
||
3385 | |||
3386 | } |
||
3387 | |||
3388 | int caselong(unsigned long val) |
||
3389 | |||
3390 | int vop=0; |
||
3391 | |||
3392 | for(;vop |
||
3393 | |||
3394 | if(val==num)break; |
||
3395 | |||
3396 | } |
||
3397 | |||
3398 | } |
||
3399 | |||
3400 | int caselonglong(unsigned long long val) |
||
3401 | |||
3402 | int vop=0; |
||
3403 | |||
3404 | for(;vop |
||
3405 | |||
3406 | if(val==num)break; |
||
3407 | |||
3408 | } |
||
3409 | |||
3410 | } |
||
3411 | |||
3412 | int do_e_axmath(int sign,int razr,char **ofsstr) |
||
3413 | |||
3414 | int negflag=0,next=0; |
||
3415 | |||
3416 | unsigned int i=0; |
||
3417 | |||
3418 | int loop=0,otok; |
||
3419 | |||
3420 | if(tok==tk_minus){ |
||
3421 | |||
3422 | negflag=1; |
||
3423 | |||
3424 | } |
||
3425 | |||
3426 | if(uselea){ |
||
3427 | |||
3428 | if(Reg32ToLea(EAX)){ |
||
3429 | |||
3430 | } |
||
3431 | |||
3432 | else if(Reg16ToLea(AX)){ |
||
3433 | |||
3434 | } |
||
3435 | |||
3436 | loopswitch: |
||
3437 | |||
3438 | // printf("tok=%d %s\n",tok,itok.name); |
||
3439 | |||
3440 | CheckConstVar3(&tok,&itok,razr); |
||
3441 | |||
3442 | #endif |
||
3443 | |||
3444 | case tk_number: |
||
3445 | |||
3446 | if(loop==0)i=postnumflag; |
||
3447 | |||
3448 | loop++; |
||
3449 | |||
3450 | (!((tok2==tk_reg32||tok2==tk_reg)&&itok2.number==EAX))&&expandvar()==FALSE){ |
||
3451 | |||
3452 | next=1; |
||
3453 | |||
3454 | } |
||
3455 | |||
3456 | nexttok(); |
||
3457 | |||
3458 | } |
||
3459 | |||
3460 | next=0; |
||
3461 | |||
3462 | case tk_apioffset: |
||
3463 | |||
3464 | op(0xB8); /* MOV AX,# */ |
||
3465 | |||
3466 | nexttok(); |
||
3467 | |||
3468 | case tk_postnumber: |
||
3469 | |||
3470 | if(next==0){ |
||
3471 | |||
3472 | op(0xB8); /* MOV AX,# */ |
||
3473 | |||
3474 | } |
||
3475 | |||
3476 | AddUndefOff(2,itok.name); |
||
3477 | |||
3478 | // itok.flag=0; //new 07.07.04 23:57 |
||
3479 | |||
3480 | else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
3481 | |||
3482 | holdnumber+=doconstdwordmath(); |
||
3483 | |||
3484 | if(loop==0)i=postnumflag; |
||
3485 | |||
3486 | loop++; |
||
3487 | |||
3488 | if(tok==tk_plus&&tok2==tk_postnumber){ |
||
3489 | |||
3490 | goto loopswitch; |
||
3491 | |||
3492 | if((i&f_reloc)!=0)AddReloc(); |
||
3493 | |||
3494 | if(razr==r16)outword(holdnumber); |
||
3495 | |||
3496 | ClearReg(AX); |
||
3497 | |||
3498 | case tk_rmnumber: |
||
3499 | |||
3500 | reg1=am32==FALSE?idxregs[0]:EAX; |
||
3501 | |||
3502 | CheckAllMassiv(bufrm,itok.size,&strinf,&itok,reg1,reg2); |
||
3503 | |||
3504 | op66(razr); |
||
3505 | |||
3506 | if((itok.rm&0x3F)==0&&am32&&itok.post==0&&(short_ok(itok.number,TRUE)==FALSE||((itok.rm&rm_mod11)==rm_mod10))){ //add |
||
3507 | |||
3508 | op(5); //add |
||
3509 | |||
3510 | else{ //lea |
||
3511 | |||
3512 | op(0x8D); op(itok.rm); |
||
3513 | |||
3514 | // if(itok.post==0)outseg(&itok,2); |
||
3515 | |||
3516 | if(itok.post!=0&&itok.post!=UNDEF_OFSET){ |
||
3517 | |||
3518 | i=outptr; |
||
3519 | |||
3520 | setwordpost(&itok); |
||
3521 | |||
3522 | } |
||
3523 | |||
3524 | } |
||
3525 | |||
3526 | oitok=itok; |
||
3527 | |||
3528 | itok.rm=tk_dword; |
||
3529 | |||
3530 | // oitok.flag|=postnumflag; |
||
3531 | |||
3532 | ClearReg(AX); |
||
3533 | |||
3534 | else nexttok(); |
||
3535 | |||
3536 | case tk_at: |
||
3537 | |||
3538 | i++; |
||
3539 | |||
3540 | case tk_id: |
||
3541 | |||
3542 | case tk_apiproc: |
||
3543 | |||
3544 | case tk_declare: |
||
3545 | |||
3546 | if((!i)|| |
||
3547 | |||
3548 | procdo(sign!=0?(razr==r16?tk_int:tk_long):(razr==r16?tk_word:tk_dword)); |
||
3549 | |||
3550 | nexttok(); |
||
3551 | |||
3552 | free(*ofsstr); |
||
3553 | |||
3554 | } |
||
3555 | |||
3556 | case tk_new: |
||
3557 | |||
3558 | clearregstat(); |
||
3559 | |||
3560 | FreeGlobalConst(); |
||
3561 | |||
3562 | if(*ofsstr){ |
||
3563 | |||
3564 | *ofsstr=NULL; |
||
3565 | |||
3566 | nexttok(); |
||
3567 | |||
3568 | default: |
||
3569 | |||
3570 | ITOK witok=itok; |
||
3571 | |||
3572 | bufrm=NULL; |
||
3573 | |||
3574 | getinto_e_ax(sign,tok,&witok,wbuf,&wstr,razr); |
||
3575 | |||
3576 | } |
||
3577 | |||
3578 | if(negflag){ |
||
3579 | |||
3580 | setzeroflag=TRUE; |
||
3581 | |||
3582 | #ifdef OPTVARCONST |
||
3583 | |||
3584 | #endif |
||
3585 | |||
3586 | // printf("tok=%d type=%d name=%s\n",tok,itok.type,itok.name); |
||
3587 | |||
3588 | do_e_axmath2(sign,razr,expand); |
||
3589 | |||
3590 | } |
||
3591 | |||
3592 | } |
||
3593 | |||
3594 | void do_e_axmath2(int sign,int razr,int expand) |
||
3595 | |||
3596 | int vop,negflag=0,next; |
||
3597 | |||
3598 | unsigned int i; |
||
3599 | |||
3600 | unsigned char oaddstack; |
||
3601 | |||
3602 | next=1; |
||
3603 | |||
3604 | i=0; |
||
3605 | |||
3606 | #ifdef OPTVARCONST |
||
3607 | |||
3608 | if(tok2==tk_number)calcnumber=TRUE; |
||
3609 | |||
3610 | if(uselea&&razr==r32){ |
||
3611 | |||
3612 | if(itok.type==tp_stopper||tok==tk_eof||itok.type==tp_compare)break; |
||
3613 | |||
3614 | |||
3615 | |||
3616 | int oldtok=tok; |
||
3617 | |||
3618 | case tk_xor: vop+=0x08; |
||
3619 | |||
3620 | case tk_and: vop+=0x18; |
||
3621 | |||
3622 | case tk_plus: |
||
3623 | |||
3624 | else{ |
||
3625 | |||
3626 | optnum=FALSE; |
||
3627 | |||
3628 | switch(tok){ |
||
3629 | |||
3630 | if((itok.flag&f_reloc)==0){ |
||
3631 | |||
3632 | } |
||
3633 | |||
3634 | case tk_postnumber: |
||
3635 | |||
3636 | op(0x05+vop); |
||
3637 | |||
3638 | else if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
3639 | |||
3640 | razr==r16?outword((unsigned int)itok.number):outdword(itok.number); |
||
3641 | |||
3642 | break; |
||
3643 | |||
3644 | op66(razr); |
||
3645 | |||
3646 | AddApiToPost(itok.number); |
||
3647 | |||
3648 | break; |
||
3649 | |||
3650 | case tk_longvar: |
||
3651 | |||
3652 | i=2; |
||
3653 | |||
3654 | case tk_wordvar: |
||
3655 | |||
3656 | |||
3657 | |||
3658 | op66(razr); |
||
3659 | |||
3660 | op(0x03+vop); |
||
3661 | |||
3662 | outaddress(&itok); |
||
3663 | |||
3664 | break; |
||
3665 | |||
3666 | i=4; |
||
3667 | |||
3668 | Float2reg32(EDX,i); |
||
3669 | |||
3670 | warningreg(regs[1][EDX]); |
||
3671 | |||
3672 | case tk_ID: |
||
3673 | |||
3674 | case tk_proc: |
||
3675 | |||
3676 | case tk_undefproc: |
||
3677 | |||
3678 | op66(razr); |
||
3679 | |||
3680 | addESP+=razr==r16?2:4; |
||
3681 | |||
3682 | addstack=FALSE; |
||
3683 | |||
3684 | addstack=oaddstack; |
||
3685 | |||
3686 | op66(razr); |
||
3687 | |||
3688 | itok.number=EDX; |
||
3689 | |||
3690 | if(vop>0x20){ |
||
3691 | |||
3692 | op(0x90+EDX); //xchg ax,dx |
||
3693 | |||
3694 | goto defreg32; |
||
3695 | |||
3696 | int vops; |
||
3697 | |||
3698 | if(i<=64)vops=r64; |
||
3699 | |||
3700 | if(i<=16)vops=r16; |
||
3701 | |||
3702 | itok.number=CX; |
||
3703 | |||
3704 | warningreg(regs[vops/2-1][ECX]); |
||
3705 | |||
3706 | case tk_reg: |
||
3707 | |||
3708 | case tk_reg32: |
||
3709 | |||
3710 | op66(razr); |
||
3711 | |||
3712 | op(0xC0+(unsigned int)itok.number*8); |
||
3713 | |||
3714 | break; |
||
3715 | |||
3716 | case tk_charvar: |
||
3717 | |||
3718 | case tk_bytevar: |
||
3719 | |||
3720 | getintoreg_32(CX,razr,sign,&ofsstr,FALSE); |
||
3721 | |||
3722 | op(0x01+vop); |
||
3723 | |||
3724 | warningreg(regs[razr/2-1][1]); |
||
3725 | |||
3726 | setzeroflag=TRUE; |
||
3727 | |||
3728 | default: valueexpected(); break; |
||
3729 | |||
3730 | if(expand==TRUE){ |
||
3731 | |||
3732 | op(0x83); |
||
3733 | |||
3734 | else if(oldtok==tk_minus)outword(0x00da); //sbb dx,0 |
||
3735 | |||
3736 | } |
||
3737 | |||
3738 | case tk_modminus: negflag=1; |
||
3739 | |||
3740 | case tk_divminus: negflag=1-negflag; |
||
3741 | |||
3742 | if(optnum==FALSE)getoperand(); |
||
3743 | |||
3744 | tok=tk_number; |
||
3745 | |||
3746 | } |
||
3747 | |||
3748 | if(negflag){ |
||
3749 | |||
3750 | negflag=0; |
||
3751 | |||
3752 | } |
||
3753 | |||
3754 | if(vop==1&&setzeroflag==0){ |
||
3755 | |||
3756 | if(optimizespeed)outword(0xC28B); //mov ax,dx |
||
3757 | |||
3758 | } |
||
3759 | |||
3760 | expand=FALSE; |
||
3761 | |||
3762 | case tk_multminus: negflag=1; |
||
3763 | |||
3764 | expand=expandvar(); //возможность расширения разрядности |
||
3765 | |||
3766 | else{ |
||
3767 | |||
3768 | optnum=FALSE; |
||
3769 | |||
3770 | if(negflag&&tok==tk_number){ |
||
3771 | |||
3772 | negflag=0; |
||
3773 | |||
3774 | switch(tok){ |
||
3775 | |||
3776 | RegMulNum(AX,itok.number,razr,sign,&expand,itok.flag); |
||
3777 | |||
3778 | case tk_qwordvar: |
||
3779 | |||
3780 | case tk_dwordvar: |
||
3781 | |||
3782 | case tk_intvar: |
||
3783 | |||
3784 | if(razr==r32&&(tok==tk_intvar||tok==tk_wordvar))goto defmul; |
||
3785 | |||
3786 | CheckAllMassiv(bufrm,i,&strinf); |
||
3787 | |||
3788 | outseg(&itok,2); |
||
3789 | |||
3790 | if(sign)op(0x28+itok.rm); |
||
3791 | |||
3792 | outaddress(&itok); |
||
3793 | |||
3794 | break; |
||
3795 | |||
3796 | i=4; |
||
3797 | |||
3798 | Float2reg32(EDX,i); |
||
3799 | |||
3800 | op(0xF7); |
||
3801 | |||
3802 | setzeroflag=FALSE; |
||
3803 | |||
3804 | break; |
||
3805 | |||
3806 | case tk_id: |
||
3807 | |||
3808 | case tk_apiproc: |
||
3809 | |||
3810 | case tk_declare: |
||
3811 | |||
3812 | op(0x50); //push AX |
||
3813 | |||
3814 | oaddstack=addstack; |
||
3815 | |||
3816 | procdo(razr==r16?(sign==0?tk_word:tk_int):(sign==0?tk_dword:tk_long)); |
||
3817 | |||
3818 | addESP-=razr==r16?2:4; |
||
3819 | |||
3820 | op(0x58+EDX); |
||
3821 | |||
3822 | warningreg(regs[razr/2-1][EDX]); |
||
3823 | |||
3824 | case tk_bits: |
||
3825 | |||
3826 | i=itok.bit.siz+itok.bit.ofs; |
||
3827 | |||
3828 | if(i<=32)vops=r32; |
||
3829 | |||
3830 | bits2reg(CX,(razr |
||
3831 | |||
3832 | if(vops==r64)vops=r32; |
||
3833 | |||
3834 | goto mulreg32; |
||
3835 | |||
3836 | i=itok.number; |
||
3837 | |||
3838 | case tk_reg32: |
||
3839 | |||
3840 | op66(razr); |
||
3841 | |||
3842 | if(sign)op(0xE8+(unsigned int)itok.number); |
||
3843 | |||
3844 | setzeroflag=FALSE; |
||
3845 | |||
3846 | case tk_postnumber: |
||
3847 | |||
3848 | op66(razr); |
||
3849 | |||
3850 | op(0xc0); |
||
3851 | |||
3852 | else if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
3853 | |||
3854 | setzeroflag=FALSE; |
||
3855 | |||
3856 | case tk_apioffset: |
||
3857 | |||
3858 | op(0x69); |
||
3859 | |||
3860 | AddApiToPost(itok.number); |
||
3861 | |||
3862 | break; |
||
3863 | |||
3864 | case tk_charvar: |
||
3865 | |||
3866 | case tk_bytevar: |
||
3867 | |||
3868 | defmul: |
||
3869 | |||
3870 | mulreg: |
||
3871 | |||
3872 | op66(razr); |
||
3873 | |||
3874 | if(sign)op(0xE8+i); /* IMUL i */ |
||
3875 | |||
3876 | next=0; |
||
3877 | |||
3878 | warningreg(regs[razr/2-1][2]); |
||
3879 | |||
3880 | break; |
||
3881 | |||
3882 | } |
||
3883 | |||
3884 | case tk_xorminus: vop+=0x10; |
||
3885 | |||
3886 | case tk_orminus: vop+=0x08; |
||
3887 | |||
3888 | if(tok==tk_number){ |
||
3889 | |||
3890 | op66(razr); |
||
3891 | |||
3892 | if((itok.flag&f_reloc)!=0)AddReloc(); |
||
3893 | |||
3894 | } |
||
3895 | |||
3896 | getintoreg_32(CX,razr,sign,&ofsstr,FALSE); |
||
3897 | |||
3898 | op66(razr); |
||
3899 | |||
3900 | op(0xC8); |
||
3901 | |||
3902 | next=0; |
||
3903 | |||
3904 | setzeroflag=TRUE; |
||
3905 | |||
3906 | case tk_ll: |
||
3907 | |||
3908 | if(tok==tk_number){ |
||
3909 | |||
3910 | if(chip>2||razr==r32){ |
||
3911 | |||
3912 | op(0x0f); |
||
3913 | |||
3914 | op(itok.number); |
||
3915 | |||
3916 | else{ |
||
3917 | |||
3918 | else if((unsigned int)itok.number!=0){ |
||
3919 | |||
3920 | outdword(0xd213c001); //ADD AX,AX ADC DX,DX |
||
3921 | |||
3922 | warningreg(begs[1]); |
||
3923 | |||
3924 | } |
||
3925 | |||
3926 | } |
||
3927 | |||
3928 | lshiftmul(itok.number,razr); |
||
3929 | |||
3930 | } |
||
3931 | |||
3932 | break; |
||
3933 | |||
3934 | tok=tk_minus; // do optimization 286+ here later |
||
3935 | |||
3936 | if(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==1)){ |
||
3937 | |||
3938 | warningreg(begs[1]); |
||
3939 | |||
3940 | else getoperand(); |
||
3941 | |||
3942 | if(expand==TRUE){ |
||
3943 | |||
3944 | op66(razr); |
||
3945 | |||
3946 | outword(0xC2a5); //SHLD DX,AX,CL |
||
3947 | |||
3948 | else |
||
3949 | |||
3950 | outword(0xfae2); //LOOP -6 |
||
3951 | |||
3952 | } |
||
3953 | |||
3954 | outword(0xE0D3); /* SHL AX,CL */ |
||
3955 | |||
3956 | break; |
||
3957 | |||
3958 | if(sign)vop=0x10; |
||
3959 | |||
3960 | if(expand==TRUE){ |
||
3961 | |||
3962 | if((unsigned int)itok.number==1){ |
||
3963 | |||
3964 | outword(0xead1); //shr dx,1 ror ax,1 |
||
3965 | |||
3966 | outword(0xc8d1); //shr dx,1 ror ax,1 |
||
3967 | |||
3968 | } |
||
3969 | |||
3970 | if(chip>2||razr==r32){ |
||
3971 | |||
3972 | op(0x0f); |
||
3973 | |||
3974 | op(itok.number); |
||
3975 | |||
3976 | op(0xc1); op(0xea+vop);//s?r dx,num |
||
3977 | |||
3978 | setzeroflag=TRUE; |
||
3979 | |||
3980 | else{ |
||
3981 | |||
3982 | getintobeg(CL,&ofsstr); |
||
3983 | |||
3984 | op(0xd1); op(0xea+vop);//s?r dx,1 |
||
3985 | |||
3986 | setzeroflag=FALSE; |
||
3987 | |||
3988 | } |
||
3989 | |||
3990 | else goto rrminus; |
||
3991 | |||
3992 | else{ |
||
3993 | |||
3994 | setzeroflag=TRUE; |
||
3995 | |||
3996 | } |
||
3997 | |||
3998 | case tk_rrminus: |
||
3999 | |||
4000 | tok=tk_minus; // do optimization 286+ here later |
||
4001 | |||
4002 | if(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==1)){ |
||
4003 | |||
4004 | warningreg(begs[1]); |
||
4005 | |||
4006 | else getoperand(); |
||
4007 | |||
4008 | if(chip>2||razr==r32){ |
||
4009 | |||
4010 | op(0x0f); |
||
4011 | |||
4012 | op66(razr); |
||
4013 | |||
4014 | setzeroflag=TRUE; |
||
4015 | |||
4016 | else{ |
||
4017 | |||
4018 | outdword(0xfae2d8d1); //rcr ax,1 //LOOP -6 |
||
4019 | |||
4020 | } |
||
4021 | |||
4022 | else{ |
||
4023 | |||
4024 | op(0xD3); op(0xE8+vop); /* SR AX,CL */ |
||
4025 | |||
4026 | } |
||
4027 | |||
4028 | break; |
||
4029 | |||
4030 | } |
||
4031 | |||
4032 | ClearReg(EAX); |
||
4033 | |||
4034 | NegReg(razr,EAX); |
||
4035 | |||
4036 | negflag=0; |
||
4037 | |||
4038 | if(next)nexttok(); |
||
4039 | |||
4040 | calcnumber=FALSE; |
||
4041 | |||
4042 | if(tok==tk_eof)unexpectedeof(); |
||
4043 | |||
4044 | } |
||
4045 | |||
4046 | void getintoal(int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr) // AH may also be changed |
||
4047 | |||
4048 | unsigned int i=0; |
||
4049 | |||
4050 | case tk_bits: |
||
4051 | |||
4052 | i=gstok->bit.siz+gstok->bit.ofs; |
||
4053 | |||
4054 | if(i<=32)razr=r32; |
||
4055 | |||
4056 | if(i<=8)razr=r8; |
||
4057 | |||
4058 | break; |
||
4059 | |||
4060 | op(0xB0); /* MOV AL,# */ |
||
4061 | |||
4062 | ConstToReg(gstok->number,AL,r8); |
||
4063 | |||
4064 | case tk_rmnumber: |
||
4065 | |||
4066 | op66(r16); |
||
4067 | |||
4068 | if(gstok->post==0)outseg(gstok,2); |
||
4069 | |||
4070 | op(gstok->rm); |
||
4071 | |||
4072 | if((gstok->flag&f_extern)==0){ |
||
4073 | |||
4074 | if(am32&&gstok->rm==rm_sib)outptr++; |
||
4075 | |||
4076 | outptr=i; |
||
4077 | |||
4078 | else setwordext(&gstok->number); |
||
4079 | |||
4080 | outaddress(gstok); |
||
4081 | |||
4082 | break; |
||
4083 | |||
4084 | op66(r16); |
||
4085 | |||
4086 | (gstok->flag&f_extern)==0?setwordpost(gstok):setwordext(&gstok->number); |
||
4087 | |||
4088 | ClearReg(AL); |
||
4089 | |||
4090 | case tk_floatvar: |
||
4091 | |||
4092 | CheckInitBP(); |
||
4093 | |||
4094 | outword(0x6a); //push 0 |
||
4095 | |||
4096 | addESP+=4; |
||
4097 | |||
4098 | outseg(gstok,2); //fld floatvar |
||
4099 | |||
4100 | op(gstok->rm); |
||
4101 | |||
4102 | fistp_stack(); |
||
4103 | |||
4104 | op(0x58); //pop EAX |
||
4105 | |||
4106 | RestoreBP(); |
||
4107 | |||
4108 | break; |
||
4109 | |||
4110 | i=4; |
||
4111 | |||
4112 | case tk_dwordvar: |
||
4113 | |||
4114 | case tk_intvar: |
||
4115 | |||
4116 | i++; |
||
4117 | |||
4118 | case tk_charvar: |
||
4119 | |||
4120 | if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){ |
||
4121 | |||
4122 | op(0xA0); //mov AL, |
||
4123 | |||
4124 | if(am32==FALSE)outword(gstok->number); |
||
4125 | |||
4126 | } |
||
4127 | |||
4128 | CheckAllMassiv(gbuf,i,gstr,gstok); |
||
4129 | |||
4130 | op(0x8A); |
||
4131 | |||
4132 | outaddress(gstok); |
||
4133 | |||
4134 | ClearReg(AL); |
||
4135 | |||
4136 | case tk_reg32: |
||
4137 | |||
4138 | i=1; |
||
4139 | |||
4140 | } |
||
4141 | |||
4142 | case tk_reg: |
||
4143 | |||
4144 | i=1; |
||
4145 | |||
4146 | } |
||
4147 | |||
4148 | beg1: |
||
4149 | |||
4150 | op(0x88+i); //mov [],AL |
||
4151 | |||
4152 | } |
||
4153 | |||
4154 | break; |
||
4155 | |||
4156 | op66(r16); |
||
4157 | |||
4158 | ClearReg(AL); break; // fix by cppcheck |
||
4159 | |||
4160 | } |
||
4161 | |||
4162 | |||
4163 | |||
4164 | { |
||
4165 | |||
4166 | int rettype=tk_beg; |
||
4167 | |||
4168 | if(CheckMinusNum()==FALSE){ |
||
4169 | |||
4170 | getoperand(am32==TRUE?EAX:BX); |
||
4171 | |||
4172 | } |
||
4173 | |||
4174 | if(tok>=tk_charvar&&tok<=tk_doublevar&&itok.npointr==0){ |
||
4175 | |||
4176 | tok=tk_number; |
||
4177 | |||
4178 | } |
||
4179 | |||
4180 | #endif |
||
4181 | |||
4182 | case tk_number: |
||
4183 | |||
4184 | i=CalcNumber(sign); |
||
4185 | |||
4186 | ConstToReg(i,AL,r8); |
||
4187 | |||
4188 | case tk_at: |
||
4189 | |||
4190 | i++; |
||
4191 | |||
4192 | case tk_id: |
||
4193 | |||
4194 | case tk_apiproc: |
||
4195 | |||
4196 | case tk_declare: |
||
4197 | |||
4198 | if((!i)||macros(sign!=0?tk_char:tk_byte)==0)procdo(sign!=0?tk_char:tk_byte); |
||
4199 | |||
4200 | if(*ofsstr){ |
||
4201 | |||
4202 | *ofsstr=NULL; |
||
4203 | |||
4204 | break; |
||
4205 | |||
4206 | SINFO bstr=strinf; |
||
4207 | |||
4208 | ITOK btok; |
||
4209 | |||
4210 | btok=itok; |
||
4211 | |||
4212 | bufrm=NULL; |
||
4213 | |||
4214 | } |
||
4215 | |||
4216 | calcnumber=FALSE; |
||
4217 | |||
4218 | if(negflag){ |
||
4219 | |||
4220 | else outword(0xD8F6);// NEG AL |
||
4221 | |||
4222 | } |
||
4223 | |||
4224 | doalmath2(sign); |
||
4225 | |||
4226 | } |
||
4227 | |||
4228 | } |
||
4229 | |||
4230 | void doalmath2(int sign) |
||
4231 | |||
4232 | int vop,i,next; |
||
4233 | |||
4234 | int negflag=0; |
||
4235 | |||
4236 | while(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){ |
||
4237 | |||
4238 | i=0; |
||
4239 | |||
4240 | #ifdef OPTVARCONST |
||
4241 | |||
4242 | if(CheckConstVar(&itok2)){ |
||
4243 | |||
4244 | calcnumber=TRUE; |
||
4245 | |||
4246 | } |
||
4247 | |||
4248 | if(tok2==tk_number)optnum=OptimNum(); |
||
4249 | |||
4250 | switch(tok){ |
||
4251 | |||
4252 | case tk_minus: vop+=0x08; |
||
4253 | |||
4254 | case tk_or: vop+=0x08; |
||
4255 | |||
4256 | if(optnum==FALSE)getoperand(); |
||
4257 | |||
4258 | tok=tk_number; |
||
4259 | |||
4260 | } |
||
4261 | |||
4262 | case tk_number: |
||
4263 | |||
4264 | if(itok.number==255&&oldtok==tk_and)break; |
||
4265 | |||
4266 | op((unsigned int)itok.number); /* OPT AL,num */ |
||
4267 | |||
4268 | case tk_rmnumber: |
||
4269 | |||
4270 | op66(r16); |
||
4271 | |||
4272 | if(itok.post==0)outseg(&itok,2); |
||
4273 | |||
4274 | op(0x8+itok.rm); |
||
4275 | |||
4276 | if((itok.flag&f_extern)==0){ |
||
4277 | |||
4278 | if(am32&&itok.rm==rm_sib)outptr++; |
||
4279 | |||
4280 | outptr=ooutptr; |
||
4281 | |||
4282 | else setwordext(&itok.number); |
||
4283 | |||
4284 | outaddress(&itok); |
||
4285 | |||
4286 | op(0xC8); |
||
4287 | |||
4288 | break; |
||
4289 | |||
4290 | op66(r16); |
||
4291 | |||
4292 | (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
4293 | |||
4294 | break; |
||
4295 | |||
4296 | i=4; |
||
4297 | |||
4298 | case tk_dwordvar: |
||
4299 | |||
4300 | case tk_intvar: |
||
4301 | |||
4302 | i++; |
||
4303 | |||
4304 | case tk_bytevar: |
||
4305 | |||
4306 | CheckAllMassiv(bufrm,i,&strinf); |
||
4307 | |||
4308 | op(0x02+vop); op(itok.rm); |
||
4309 | |||
4310 | break; |
||
4311 | |||
4312 | case tk_id: |
||
4313 | |||
4314 | case tk_apiproc: |
||
4315 | |||
4316 | case tk_declare: |
||
4317 | |||
4318 | op(0x50); //push AX |
||
4319 | |||
4320 | unsigned char oaddstack; |
||
4321 | |||
4322 | addstack=FALSE; |
||
4323 | |||
4324 | addstack=oaddstack; |
||
4325 | |||
4326 | op66(r16); |
||
4327 | |||
4328 | itok.number=CX; |
||
4329 | |||
4330 | if(vop>0x20){ |
||
4331 | |||
4332 | op(0x90+CX); //xchg ax,Cx |
||
4333 | |||
4334 | goto defbeg; |
||
4335 | |||
4336 | int razr; |
||
4337 | |||
4338 | if(i<=64)razr=r64; |
||
4339 | |||
4340 | if(i<=16)razr=r16; |
||
4341 | |||
4342 | bits2reg(CL,razr); |
||
4343 | |||
4344 | if(razr==r64)razr=r32; |
||
4345 | |||
4346 | goto defbeg; |
||
4347 | |||
4348 | i=4; |
||
4349 | |||
4350 | Float2reg32(EAX,i); |
||
4351 | |||
4352 | case tk_beg: |
||
4353 | |||
4354 | op(vop); |
||
4355 | |||
4356 | break; |
||
4357 | |||
4358 | case tk_reg: |
||
4359 | |||
4360 | op66(r16); |
||
4361 | |||
4362 | warningreg(regs[0][1]); |
||
4363 | |||
4364 | itok.number=CL; |
||
4365 | |||
4366 | goto defbeg; |
||
4367 | |||
4368 | } |
||
4369 | |||
4370 | if(expand==TRUE){ |
||
4371 | |||
4372 | outword(0xd480); //ADC AH,0 |
||
4373 | |||
4374 | } |
||
4375 | |||
4376 | outword(0xdc80); //SBB AH,0 |
||
4377 | |||
4378 | } |
||
4379 | |||
4380 | } |
||
4381 | |||
4382 | case tk_modminus: negflag=1; |
||
4383 | |||
4384 | case tk_divminus: negflag=1-negflag; |
||
4385 | |||
4386 | if(optnum==FALSE)getoperand(); |
||
4387 | |||
4388 | tok=tk_number; |
||
4389 | |||
4390 | } |
||
4391 | |||
4392 | if(negflag){ |
||
4393 | |||
4394 | negflag=0; |
||
4395 | |||
4396 | itok.number&=255; |
||
4397 | |||
4398 | if(itok.number==0)DevideZero(); |
||
4399 | |||
4400 | op(0x24); /* AND AL,number-1 */ |
||
4401 | |||
4402 | setzeroflag=TRUE; |
||
4403 | |||
4404 | else{ |
||
4405 | |||
4406 | if(sign)cbw(); |
||
4407 | |||
4408 | } |
||
4409 | |||
4410 | if(sign)outword(0xF9F6); /* IDIV CL */ |
||
4411 | |||
4412 | outword(0xE088);// MOV AL,AH |
||
4413 | |||
4414 | warningreg(begs[1]); |
||
4415 | |||
4416 | } |
||
4417 | |||
4418 | else{ |
||
4419 | |||
4420 | case 0: |
||
4421 | |||
4422 | break; |
||
4423 | |||
4424 | case 2: |
||
4425 | |||
4426 | if(sign)op(0xf8); |
||
4427 | |||
4428 | setzeroflag=TRUE; |
||
4429 | |||
4430 | default: |
||
4431 | |||
4432 | if(vop!=NUMNUM){ |
||
4433 | |||
4434 | op(0xB1); op(vop); /* MOV CL,num */ |
||
4435 | |||
4436 | if(sign)op(0xF8); // SAR AL,CL |
||
4437 | |||
4438 | warningreg(begs[1]); |
||
4439 | |||
4440 | else{ |
||
4441 | |||
4442 | if(sign)op(0xF8); /* SAR AL,num */ |
||
4443 | |||
4444 | op(vop); |
||
4445 | |||
4446 | } |
||
4447 | |||
4448 | } |
||
4449 | |||
4450 | if(expand==FALSE){ |
||
4451 | |||
4452 | //замена деления умножением |
||
4453 | |||
4454 | if(chip>4){ |
||
4455 | |||
4456 | op66(r16); |
||
4457 | |||
4458 | op(itok.number); |
||
4459 | |||
4460 | } |
||
4461 | |||
4462 | op(0xB2); //mov DL,num |
||
4463 | |||
4464 | outword(0xE2F6); //mul DL |
||
4465 | |||
4466 | } |
||
4467 | |||
4468 | setzeroflag=FALSE; |
||
4469 | |||
4470 | } |
||
4471 | |||
4472 | else xorAHAH(); |
||
4473 | |||
4474 | op(0xB1); /* MOV CL,# */ |
||
4475 | |||
4476 | if(sign)outword(0xF9F6); /* IDIV CL */ |
||
4477 | |||
4478 | setzeroflag=FALSE; |
||
4479 | |||
4480 | } |
||
4481 | |||
4482 | } |
||
4483 | |||
4484 | else{ |
||
4485 | |||
4486 | i=4; |
||
4487 | |||
4488 | Float2reg32(ECX,i); |
||
4489 | |||
4490 | tok=tk_beg; |
||
4491 | |||
4492 | } |
||
4493 | |||
4494 | if(sign)cbw(); |
||
4495 | |||
4496 | } |
||
4497 | |||
4498 | case tk_rmnumber: |
||
4499 | |||
4500 | getintoreg_32(CX,r16,sign,&ofsstr,FALSE); |
||
4501 | |||
4502 | else outword(0xF1F6); // DIV CL |
||
4503 | |||
4504 | warningreg(regs[0][1]); |
||
4505 | |||
4506 | case tk_qwordvar: |
||
4507 | |||
4508 | case tk_longvar: |
||
4509 | |||
4510 | i+=2; |
||
4511 | |||
4512 | case tk_wordvar: |
||
4513 | |||
4514 | case tk_charvar: |
||
4515 | |||
4516 | i++; |
||
4517 | |||
4518 | outseg(&itok,2); |
||
4519 | |||
4520 | if(sign)op(0x38+itok.rm); |
||
4521 | |||
4522 | outaddress(&itok); |
||
4523 | |||
4524 | break; |
||
4525 | |||
4526 | int razr; |
||
4527 | |||
4528 | if(i<=64)razr=r64; |
||
4529 | |||
4530 | if(i<=16)razr=r16; |
||
4531 | |||
4532 | bits2reg(CL,razr); |
||
4533 | |||
4534 | if(razr==r64)razr=r32; |
||
4535 | |||
4536 | goto defdiv; |
||
4537 | |||
4538 | case tk_id: |
||
4539 | |||
4540 | case tk_apiproc: |
||
4541 | |||
4542 | case tk_declare: |
||
4543 | |||
4544 | op(0x50); //push AX |
||
4545 | |||
4546 | unsigned char oaddstack; |
||
4547 | |||
4548 | addstack=FALSE; |
||
4549 | |||
4550 | addstack=oaddstack; |
||
4551 | |||
4552 | op66(r16); |
||
4553 | |||
4554 | itok.number=CX; |
||
4555 | |||
4556 | op66(r16); |
||
4557 | |||
4558 | case tk_beg: |
||
4559 | |||
4560 | op(0xF6); |
||
4561 | |||
4562 | else op(0xF0+(unsigned int)itok.number); |
||
4563 | |||
4564 | break; |
||
4565 | |||
4566 | case tk_reg: |
||
4567 | |||
4568 | op66(r16); |
||
4569 | |||
4570 | warningreg(regs[0][1]); |
||
4571 | |||
4572 | itok.number=CL; |
||
4573 | |||
4574 | goto defdiv; |
||
4575 | |||
4576 | } |
||
4577 | |||
4578 | } |
||
4579 | |||
4580 | break; |
||
4581 | |||
4582 | case tk_mult: |
||
4583 | |||
4584 | if(optnum==FALSE)getoperand(); |
||
4585 | |||
4586 | tok=tk_number; |
||
4587 | |||
4588 | } |
||
4589 | |||
4590 | case tk_number: |
||
4591 | |||
4592 | itok.number=-itok.number; |
||
4593 | |||
4594 | } |
||
4595 | |||
4596 | switch((unsigned int)itok.number){ |
||
4597 | |||
4598 | outword(0x00B0); |
||
4599 | |||
4600 | expand=FALSE; |
||
4601 | |||
4602 | break; /* AL * 1 = AL */ |
||
4603 | |||
4604 | if(expand==TRUE){ |
||
4605 | |||
4606 | else xorAHAH(); |
||
4607 | |||
4608 | outword(0xC000+expand); // AL * 2 = ADD AL,AL |
||
4609 | |||
4610 | break; |
||
4611 | |||
4612 | vop=caselong(itok.number); |
||
4613 | |||
4614 | if(chip<1){ |
||
4615 | |||
4616 | if(optimizespeed==FALSE&&sign==FALSE)goto num_imul; |
||
4617 | |||
4618 | else xorAHAH(); |
||
4619 | |||
4620 | op(0xB1); op(vop); /* MOV CL,num */ |
||
4621 | |||
4622 | warningreg(begs[1]); |
||
4623 | |||
4624 | else{ |
||
4625 | |||
4626 | if(optimizespeed==FALSE&&sign==FALSE)goto num_imul; |
||
4627 | |||
4628 | else xorAHAH(); |
||
4629 | |||
4630 | } |
||
4631 | |||
4632 | op(vop); |
||
4633 | |||
4634 | } |
||
4635 | |||
4636 | } |
||
4637 | |||
4638 | speedmul(itok.number,r8)!=FALSE); |
||
4639 | |||
4640 | num_imul: |
||
4641 | |||
4642 | op((unsigned int)itok.number); |
||
4643 | |||
4644 | else outword(0xE1F6); // MUL CL |
||
4645 | |||
4646 | warningreg(begs[1]); |
||
4647 | |||
4648 | } |
||
4649 | |||
4650 | case tk_rmnumber: |
||
4651 | |||
4652 | getintoreg_32(CX,r16,sign,&ofsstr,FALSE); |
||
4653 | |||
4654 | else outword(0xE1F6); // MUL CL |
||
4655 | |||
4656 | warningreg(regs[0][1]); |
||
4657 | |||
4658 | case tk_doublevar: |
||
4659 | |||
4660 | case tk_floatvar: |
||
4661 | |||
4662 | itok.number=ECX; |
||
4663 | |||
4664 | setzeroflag=FALSE; |
||
4665 | |||
4666 | break; |
||
4667 | |||
4668 | i=4; |
||
4669 | |||
4670 | case tk_dwordvar: |
||
4671 | |||
4672 | case tk_intvar: |
||
4673 | |||
4674 | i++; |
||
4675 | |||
4676 | case tk_bytevar: |
||
4677 | |||
4678 | CheckAllMassiv(bufrm,i,&strinf); |
||
4679 | |||
4680 | op(0xF6); |
||
4681 | |||
4682 | else op(0x20+itok.rm); |
||
4683 | |||
4684 | setzeroflag=FALSE; |
||
4685 | |||
4686 | case tk_bits: |
||
4687 | |||
4688 | i=itok.bit.siz+itok.bit.ofs; |
||
4689 | |||
4690 | if(i<=32)razr=r32; |
||
4691 | |||
4692 | if(i<=8)razr=r8; |
||
4693 | |||
4694 | itok.number=CL; |
||
4695 | |||
4696 | warningreg(razr==r8?begs[1]:(regs[razr/2-1][1])); |
||
4697 | |||
4698 | case tk_ID: |
||
4699 | |||
4700 | case tk_proc: |
||
4701 | |||
4702 | case tk_undefproc: |
||
4703 | |||
4704 | op66(r16); |
||
4705 | |||
4706 | addESP+=2; |
||
4707 | |||
4708 | oaddstack=addstack; |
||
4709 | |||
4710 | procdo(sign!=0?tk_char:tk_byte); |
||
4711 | |||
4712 | addESP-=2; |
||
4713 | |||
4714 | op(0x58+DX); |
||
4715 | |||
4716 | warningreg(regs[0][DX]); |
||
4717 | |||
4718 | defmul: |
||
4719 | |||
4720 | if(sign)op(0xE8+(unsigned int)itok.number); |
||
4721 | |||
4722 | setzeroflag=FALSE; |
||
4723 | |||
4724 | case tk_reg32: |
||
4725 | |||
4726 | if((unsigned int)itok.number>BX){ |
||
4727 | |||
4728 | op(0x89); /* MOV CX,reg */ |
||
4729 | |||
4730 | op(0xC1+(unsigned int)itok.number*8); /* MOV instr */ |
||
4731 | |||
4732 | } |
||
4733 | |||
4734 | default: valueexpected(); break; |
||
4735 | |||
4736 | break; |
||
4737 | |||
4738 | case tk_andminus: vop+=0x18; |
||
4739 | |||
4740 | getoperand(); |
||
4741 | |||
4742 | itok.number=-itok.number; |
||
4743 | |||
4744 | op((unsigned int)itok.number); |
||
4745 | |||
4746 | else{ |
||
4747 | |||
4748 | if(optimizespeed&&(chip==5||chip==6)){ |
||
4749 | |||
4750 | outdword(0xC1FEFFE1); //and CL,-1 inc CL |
||
4751 | |||
4752 | else outword(0xD9F6); // NEG CL |
||
4753 | |||
4754 | op(0xC8); /* opt AL,CL */ |
||
4755 | |||
4756 | next=0; |
||
4757 | |||
4758 | setzeroflag=TRUE; |
||
4759 | |||
4760 | case tk_rr: |
||
4761 | |||
4762 | if(sign)vop+=0x10; |
||
4763 | |||
4764 | getoperand(); |
||
4765 | |||
4766 | if((unsigned int)itok.number==1){ |
||
4767 | |||
4768 | op(0xD0+expand); op(0xE0+vop); /* SR AL,1 */ |
||
4769 | |||
4770 | else if((unsigned int)itok.number!=0){ |
||
4771 | |||
4772 | else{ |
||
4773 | |||
4774 | op(0xC0+expand); op(0xE0+vop); /* SR AL,imm8 */ |
||
4775 | |||
4776 | if(cpu<2)cpu=2; |
||
4777 | |||
4778 | } |
||
4779 | |||
4780 | } |
||
4781 | |||
4782 | break; |
||
4783 | |||
4784 | vop=8; |
||
4785 | |||
4786 | case tk_llminus: |
||
4787 | |||
4788 | llminus: |
||
4789 | |||
4790 | getintobeg(CL,&ofsstr); |
||
4791 | |||
4792 | } |
||
4793 | |||
4794 | if(expand==TRUE)op66(r16); |
||
4795 | |||
4796 | setzeroflag=TRUE; |
||
4797 | |||
4798 | break; |
||
4799 | |||
4800 | } |
||
4801 | |||
4802 | if(optimizespeed&&(chip==5||chip==6))outdword(0xC0FEFF34); //xor AL,-1 AL++ |
||
4803 | |||
4804 | negflag=0; |
||
4805 | |||
4806 | } |
||
4807 | |||
4808 | ClearReg(AX); |
||
4809 | |||
4810 | #ifdef OPTVARCONST |
||
4811 | |||
4812 | #endif |
||
4813 | |||
4814 | } |
||
4815 | |||
4816 | /* =============== doreg_32(), dobeg(), doseg() ===============*/ |
||
4817 | |||
4818 | int doreg_32(int reg,int razr,int terminater) |
||
4819 | |||
4820 | unsigned char next=1; |
||
4821 | |||
4822 | int i; |
||
4823 | |||
4824 | unsigned long ii; |
||
4825 | |||
4826 | int rrettype,pointr=0; |
||
4827 | |||
4828 | char *ofsstr=NULL; |
||
4829 | |||
4830 | reg1=idxregs[1]; |
||
4831 | |||
4832 | } |
||
4833 | |||
4834 | if(reg==ESP)RestoreStack(); |
||
4835 | |||
4836 | nexttok(); |
||
4837 | |||
4838 | case tk_assign://= |
||
4839 | |||
4840 | if(!((tok2==tk_reg||tok2==tk_reg32||tok2==tk_beg)&&ScanTok3()==terminater)){ |
||
4841 | |||
4842 | } |
||
4843 | |||
4844 | nexttok(); |
||
4845 | |||
4846 | case tk_beg: |
||
4847 | |||
4848 | break; |
||
4849 | |||
4850 | i=r16; |
||
4851 | |||
4852 | case tk_reg32: |
||
4853 | |||
4854 | break; |
||
4855 | |||
4856 | if(i!=razr||RegToReg(reg,itok.number,i)==NOINREG)goto nn1; |
||
4857 | |||
4858 | if(am32)idxregs[4]=255; |
||
4859 | |||
4860 | } |
||
4861 | |||
4862 | int retreg; |
||
4863 | |||
4864 | GetEndLex(terminater); |
||
4865 | |||
4866 | else tok=tk_reg32; |
||
4867 | |||
4868 | goto nn1; |
||
4869 | |||
4870 | } |
||
4871 | |||
4872 | convert_type(&sign,&rrettype,&pointr,am32==TRUE?reg:BX); |
||
4873 | |||
4874 | if(am32)idxregs[4]=255; |
||
4875 | |||
4876 | next=0; |
||
4877 | |||
4878 | IDZToReg(ofsstr,reg,razr); |
||
4879 | |||
4880 | } |
||
4881 | |||
4882 | } |
||
4883 | |||
4884 | nexttok(); |
||
4885 | |||
4886 | } |
||
4887 | |||
4888 | if(tok2==tk_assign){ |
||
4889 | |||
4890 | // puts("end MultAssign"); |
||
4891 | |||
4892 | free(ofsstr); |
||
4893 | |||
4894 | } |
||
4895 | |||
4896 | op66(razr); |
||
4897 | |||
4898 | op(0xC0+reg+hnumber*8); //mov reg,AX |
||
4899 | |||
4900 | next=0; |
||
4901 | |||
4902 | IDZToReg(ofsstr,reg,razr); |
||
4903 | |||
4904 | }*/ |
||
4905 | |||
4906 | break; |
||
4907 | |||
4908 | // printf("tok=%d %s\n",tok,itok.name); |
||
4909 | |||
4910 | if(tok==tk_new||tok==tk_delete){ |
||
4911 | |||
4912 | else{ |
||
4913 | |||
4914 | terminater=next=0; |
||
4915 | |||
4916 | if(am32)idxregs[4]=255; |
||
4917 | |||
4918 | GenRegToReg(reg,AX,(am32+1)*2); |
||
4919 | |||
4920 | clearregstat(); |
||
4921 | |||
4922 | FreeGlobalConst(); |
||
4923 | |||
4924 | if(ofsstr){ |
||
4925 | |||
4926 | ofsstr=NULL; |
||
4927 | |||
4928 | break; |
||
4929 | |||
4930 | nn1: |
||
4931 | |||
4932 | if(reg==AX){ |
||
4933 | |||
4934 | |||
4935 | |||
4936 | convert_returnvalue(razr==r16?tk_word:tk_dword,rrettype); |
||
4937 | |||
4938 | else{ |
||
4939 | |||
4940 | rettype=getintobeg(reg,&ofsstr); |
||
4941 | |||
4942 | dobegmath(reg); |
||
4943 | |||
4944 | } |
||
4945 | |||
4946 | op(0x0F); |
||
4947 | |||
4948 | else op(0xBE); |
||
4949 | |||
4950 | } |
||
4951 | |||
4952 | if(rrettype==tk_int||rrettype==tk_word)next=r16; |
||
4953 | |||
4954 | rettype=getintoreg(reg,next,sign,&ofsstr); |
||
4955 | |||
4956 | op66(r32); |
||
4957 | |||
4958 | if(!sign)op(0xB7); |
||
4959 | |||
4960 | |||
4961 | |||
4962 | } |
||
4963 | |||
4964 | next=0; |
||
4965 | |||
4966 | IDZToReg(ofsstr,reg,razr); |
||
4967 | |||
4968 | } |
||
4969 | |||
4970 | case tk_plusplus: op66(razr); op(0x40+reg); |
||
4971 | |||
4972 | break; |
||
4973 | |||
4974 | ClearReg(reg); |
||
4975 | |||
4976 | case tk_cdecl: |
||
4977 | |||
4978 | case tk_fastcall: |
||
4979 | |||
4980 | vop=tok; |
||
4981 | |||
4982 | if(tok!=tk_openbracket){ |
||
4983 | |||
4984 | FindStopTok(); |
||
4985 | |||
4986 | case tk_openbracket: //вызов процедуры по адресу в регистре |
||
4987 | |||
4988 | i=0; |
||
4989 | |||
4990 | case tk_cdecl: |
||
4991 | |||
4992 | i=swapparam(); |
||
4993 | |||
4994 | case tk_pascal: |
||
4995 | |||
4996 | break; |
||
4997 | |||
4998 | doregparams(); |
||
4999 | |||
5000 | default: |
||
5001 | |||
5002 | else doparams(); |
||
5003 | |||
5004 | if(vop!=tk_cdecl)i=0; |
||
5005 | |||
5006 | op(0xFF); |
||
5007 | |||
5008 | if(i)CorrectStack(i); |
||
5009 | |||
5010 | #ifdef OPTVARCONST |
||
5011 | |||
5012 | #endif |
||
5013 | |||
5014 | case tk_swap: |
||
5015 | |||
5016 | switch(tok){ |
||
5017 | |||
5018 | case tk_longvar: |
||
5019 | |||
5020 | if(razr==r16)swaperror(); |
||
5021 | |||
5022 | goto swapint; |
||
5023 | |||
5024 | case tk_wordvar: |
||
5025 | |||
5026 | if(razr==r32)swaperror(); |
||
5027 | |||
5028 | ClearReg(reg); |
||
5029 | |||
5030 | op66(razr); |
||
5031 | |||
5032 | op(0x87); |
||
5033 | |||
5034 | outaddress(&itok); |
||
5035 | |||
5036 | case tk_reg32: |
||
5037 | |||
5038 | goto swapreg; |
||
5039 | |||
5040 | if(razr==r32)swaperror(); |
||
5041 | |||
5042 | if(reg!=(int)itok.number){ |
||
5043 | |||
5044 | op66(razr); |
||
5045 | |||
5046 | else if((unsigned int)itok.number==AX)op(0x90+reg); |
||
5047 | |||
5048 | op(0x87); |
||
5049 | |||
5050 | } |
||
5051 | |||
5052 | else waralreadinitreg(regs[razr/4][reg],regs[razr/4][itok.number]); |
||
5053 | |||
5054 | break; |
||
5055 | |||
5056 | } |
||
5057 | |||
5058 | case tk_xorequals: vop+=0x08; |
||
5059 | |||
5060 | case tk_andequals: vop+=0x18; |
||
5061 | |||
5062 | case tk_plusequals: |
||
5063 | |||
5064 | if(am32&&uselea&&tok==tk_plusequals){ |
||
5065 | |||
5066 | next=0; |
||
5067 | |||
5068 | } |
||
5069 | |||
5070 | if(CheckAddOnly()){ |
||
5071 | |||
5072 | cha2=' '; |
||
5073 | |||
5074 | else tok=tk_minus; |
||
5075 | |||
5076 | else doregmath_32(reg,razr,0,&ofsstr); |
||
5077 | |||
5078 | break; |
||
5079 | |||
5080 | getoperand(reg==BX?SI:BX); |
||
5081 | |||
5082 | CheckMinusNum(); |
||
5083 | |||
5084 | int opost; |
||
5085 | |||
5086 | switch(tok){ |
||
5087 | |||
5088 | case tk_undefofs: |
||
5089 | |||
5090 | rrec=itok.rec; |
||
5091 | |||
5092 | char uname[IDLENGTH]; |
||
5093 | |||
5094 | if(itok.flag&f_extern)goto addnum; |
||
5095 | |||
5096 | case tk_number: |
||
5097 | |||
5098 | next=0; |
||
5099 | |||
5100 | if(reg==EAX){ |
||
5101 | |||
5102 | if((tok2==tk_reg||tok2==tk_reg32)&&itok2.number==ECX)sign=EDX; |
||
5103 | |||
5104 | } |
||
5105 | |||
5106 | op66(razr); |
||
5107 | |||
5108 | if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii); |
||
5109 | |||
5110 | if((postnumflag&f_reloc)!=0)AddReloc(); |
||
5111 | |||
5112 | } |
||
5113 | |||
5114 | } |
||
5115 | |||
5116 | if(sign==EAX)do_e_axmath2(0,razr,0); |
||
5117 | |||
5118 | itok.number=sign; |
||
5119 | |||
5120 | } |
||
5121 | |||
5122 | addnum: |
||
5123 | |||
5124 | if(reg==AX)op(0x05+vop); |
||
5125 | |||
5126 | op(0x81); |
||
5127 | |||
5128 | } |
||
5129 | |||
5130 | itok.post=opost; |
||
5131 | |||
5132 | else{ |
||
5133 | |||
5134 | if(i==tk_undefofs)AddUndefOff(2,uname); |
||
5135 | |||
5136 | razr==r16?outword(ii):outdword(ii); |
||
5137 | |||
5138 | case tk_qwordvar: |
||
5139 | |||
5140 | case tk_dwordvar: |
||
5141 | |||
5142 | goto wordadd; |
||
5143 | |||
5144 | case tk_wordvar: |
||
5145 | |||
5146 | if(razr==r32)valueexpected(); |
||
5147 | |||
5148 | CheckAllMassiv(bufrm,i,&strinf,&itok,reg1,reg2); |
||
5149 | |||
5150 | outseg(&itok,2); |
||
5151 | |||
5152 | op(reg*8+itok.rm); |
||
5153 | |||
5154 | break; |
||
5155 | |||
5156 | if(razr==r32)valueexpected(); |
||
5157 | |||
5158 | addreg: |
||
5159 | |||
5160 | op(0x01+vop); |
||
5161 | |||
5162 | break; |
||
5163 | |||
5164 | case tk_id: |
||
5165 | |||
5166 | case tk_apiproc: |
||
5167 | |||
5168 | case tk_declare: |
||
5169 | |||
5170 | if(reg==EAX){ |
||
5171 | |||
5172 | op(0x50); //push AX |
||
5173 | |||
5174 | warningreg(regs[razr/2-1][EDX]); |
||
5175 | |||
5176 | addstack=FALSE; |
||
5177 | |||
5178 | procdo(razr==r16?tk_word:tk_dword); |
||
5179 | |||
5180 | nexttok(); |
||
5181 | |||
5182 | next=0; |
||
5183 | |||
5184 | if(reg==EAX){ |
||
5185 | |||
5186 | addESP-=razr==r16?2:4; |
||
5187 | |||
5188 | op(0x58+EDX); //pop dx |
||
5189 | |||
5190 | op66(razr); |
||
5191 | |||
5192 | } |
||
5193 | |||
5194 | op(0x01+vop); |
||
5195 | |||
5196 | } |
||
5197 | |||
5198 | op66(razr); |
||
5199 | |||
5200 | op(0xc0+reg); //add reg,ax |
||
5201 | |||
5202 | break; |
||
5203 | |||
5204 | if(razr==r32)valueexpected(); |
||
5205 | |||
5206 | case tk_charvar: |
||
5207 | |||
5208 | defadd: |
||
5209 | |||
5210 | getintoreg_32(ECX,razr,sign,&ofsstr); |
||
5211 | |||
5212 | sign=CX; //sign исп как пром регистр |
||
5213 | |||
5214 | else{ |
||
5215 | |||
5216 | sign=EAX; |
||
5217 | |||
5218 | warningreg(regs[razr/2-1][sign]); |
||
5219 | |||
5220 | op(0x01+vop); |
||
5221 | |||
5222 | next=0; |
||
5223 | |||
5224 | default: valueexpected(); break; |
||
5225 | |||
5226 | break; |
||
5227 | |||
5228 | case tk_llequals: |
||
5229 | |||
5230 | getoperand(am32==TRUE?ECX:reg==BX?SI:BX); |
||
5231 | |||
5232 | if(tok==tk_number){ |
||
5233 | |||
5234 | next=0; |
||
5235 | |||
5236 | if(reg==ECX)regshifterror(); |
||
5237 | |||
5238 | dobegmath(CL); |
||
5239 | |||
5240 | ConstToReg(ii,CL,r8); |
||
5241 | |||
5242 | } |
||
5243 | |||
5244 | op66(razr); |
||
5245 | |||
5246 | } /* SHL reg,1 */ |
||
5247 | |||
5248 | if(chip<2&&razr==r16){ |
||
5249 | |||
5250 | warningreg(begs[1]); |
||
5251 | |||
5252 | goto shiftcl; |
||
5253 | |||
5254 | else{ |
||
5255 | |||
5256 | op(0xC1); op(0xE0+reg+vop); /* SHL reg,imm8 */ |
||
5257 | |||
5258 | if(cpu<2)cpu=2; |
||
5259 | |||
5260 | } |
||
5261 | |||
5262 | else if(reg!=CX){ |
||
5263 | |||
5264 | getintobeg(CL,&ofsstr); |
||
5265 | |||
5266 | warningreg(begs[1]); |
||
5267 | |||
5268 | next=0; |
||
5269 | |||
5270 | shiftcl: |
||
5271 | |||
5272 | op(0xD3); op(0xE0+vop+reg); /* SHL AX,CL */ |
||
5273 | |||
5274 | else regshifterror(); |
||
5275 | |||
5276 | case tk_multequals: |
||
5277 | |||
5278 | getoperand(reg==BX?SI:BX); |
||
5279 | |||
5280 | if(tok==tk_number){ |
||
5281 | |||
5282 | |||
5283 | |||
5284 | if(reg==EAX)sign=ECX; |
||
5285 | |||
5286 | if(sign==EAX)do_e_axmath2(0,razr,0); |
||
5287 | |||
5288 | ConstToReg(ii,sign,razr); |
||
5289 | |||
5290 | } |
||
5291 | |||
5292 | RegMulNum(reg,ii,razr,0,&i,itok.flag); |
||
5293 | |||
5294 | else{ |
||
5295 | |||
5296 | else{ |
||
5297 | |||
5298 | getintoreg_32(ECX,razr,sign,&ofsstr); |
||
5299 | |||
5300 | sign=CX; //sign исп как пром регистр |
||
5301 | |||
5302 | else{ |
||
5303 | |||
5304 | sign=EAX; |
||
5305 | |||
5306 | mulreg: |
||
5307 | |||
5308 | ClearReg(sign); |
||
5309 | |||
5310 | outword(0xAF0F); |
||
5311 | |||
5312 | next=0; |
||
5313 | |||
5314 | } |
||
5315 | |||
5316 | case tk_divequals: |
||
5317 | |||
5318 | ClearReg(reg); |
||
5319 | |||
5320 | if(tok==tk_number){ |
||
5321 | |||
5322 | next=0; |
||
5323 | |||
5324 | op66(razr); |
||
5325 | |||
5326 | addESP+=razr==r16?2:4; |
||
5327 | |||
5328 | do_e_axmath2(0,razr,0); |
||
5329 | |||
5330 | goto divreg; |
||
5331 | |||
5332 | if((vop=caselong(ii))!=NUMNUM&&(!(reg==ECX&&chip<2))){ |
||
5333 | |||
5334 | if(chip<2&&razr==r16){ |
||
5335 | |||
5336 | op(0xD3); |
||
5337 | |||
5338 | warningreg(begs[1]); |
||
5339 | |||
5340 | } |
||
5341 | |||
5342 | op66(razr); |
||
5343 | |||
5344 | op(0xE8+reg); // SHR reg,num |
||
5345 | |||
5346 | } |
||
5347 | |||
5348 | } |
||
5349 | |||
5350 | if(reg!=EAX){ |
||
5351 | |||
5352 | op(0x90+reg); //xchg reg,AX |
||
5353 | |||
5354 | DivNum(ii,razr,0); |
||
5355 | |||
5356 | op66(razr); |
||
5357 | |||
5358 | warningreg(regs[razr/2-1][EAX]); |
||
5359 | |||
5360 | } |
||
5361 | |||
5362 | } |
||
5363 | |||
5364 | if(reg!=EAX){ |
||
5365 | |||
5366 | op(0x90+reg); //xchg reg,AX |
||
5367 | |||
5368 | DivMod(0,0,razr,0); |
||
5369 | |||
5370 | if(reg!=EAX){ |
||
5371 | |||
5372 | op(0x90+reg); //xchg reg,AX |
||
5373 | |||
5374 | ClearReg(AX); |
||
5375 | |||
5376 | } |
||
5377 | |||
5378 | op66(razr); |
||
5379 | |||
5380 | addESP+=razr==r16?2:4; |
||
5381 | |||
5382 | divreg: |
||
5383 | |||
5384 | sign=reg; |
||
5385 | |||
5386 | sign=ECX; |
||
5387 | |||
5388 | ClearReg(CX); |
||
5389 | |||
5390 | addESP-=razr==r16?2:4; |
||
5391 | |||
5392 | op66(razr); |
||
5393 | |||
5394 | op66(razr); |
||
5395 | |||
5396 | op(0xF0+sign); // DIV reg |
||
5397 | |||
5398 | if(reg!=EAX){ |
||
5399 | |||
5400 | op(0x89); |
||
5401 | |||
5402 | } |
||
5403 | |||
5404 | } |
||
5405 | |||
5406 | ClearReg(AX); |
||
5407 | |||
5408 | } |
||
5409 | |||
5410 | default: operatorexpected(); break; |
||
5411 | |||
5412 | if(next)nexttok(); |
||
5413 | |||
5414 | if(razr==r32&&cpu<3)cpu=3; |
||
5415 | |||
5416 | return rettype; |
||
5417 | |||
5418 | |||
5419 | |||
5420 | { |
||
5421 | |||
5422 | if(num==0){ |
||
5423 | |||
5424 | ZeroReg(reg,razr); |
||
5425 | |||
5426 | } |
||
5427 | |||
5428 | } |
||
5429 | |||
5430 | if(num<65536&&razr==r32)nrazr=razr=r16; |
||
5431 | |||
5432 | if(reg==AX)op(0x0C); |
||
5433 | |||
5434 | op(0x80); |
||
5435 | |||
5436 | } |
||
5437 | |||
5438 | return TRUE; |
||
5439 | |||
5440 | if(nrazr==r16){ |
||
5441 | |||
5442 | if(reg==AX)op(0x0D); |
||
5443 | |||
5444 | op(0x81); |
||
5445 | |||
5446 | } |
||
5447 | |||
5448 | return TRUE; |
||
5449 | |||
5450 | } |
||
5451 | |||
5452 | if(vop==0x28){ //-= |
||
5453 | |||
5454 | op(0x48+reg); |
||
5455 | |||
5456 | return TRUE; |
||
5457 | |||
5458 | if(vop==0){ //+= |
||
5459 | |||
5460 | op(0x40+reg); |
||
5461 | |||
5462 | return TRUE; |
||
5463 | |||
5464 | } |
||
5465 | |||
5466 | if(vop==0x28){ //-= |
||
5467 | |||
5468 | op(0x48+reg); |
||
5469 | |||
5470 | return TRUE; |
||
5471 | |||
5472 | if(vop==0){ //+= |
||
5473 | |||
5474 | op(0x40+reg); |
||
5475 | |||
5476 | op(0x40+reg); |
||
5477 | |||
5478 | return TRUE; |
||
5479 | |||
5480 | } |
||
5481 | |||
5482 | (razr==r32&&num==0xffffffff)){ |
||
5483 | |||
5484 | op66(razr); |
||
5485 | |||
5486 | setzeroflag=TRUE; |
||
5487 | |||
5488 | } |
||
5489 | |||
5490 | op66(razr); |
||
5491 | |||
5492 | setzeroflag=TRUE; |
||
5493 | |||
5494 | } |
||
5495 | |||
5496 | if(vop==0x30){ //^= |
||
5497 | |||
5498 | op66(razr); |
||
5499 | |||
5500 | op(0xD0+reg); //Not reg |
||
5501 | |||
5502 | return TRUE; |
||
5503 | |||
5504 | } |
||
5505 | |||
5506 | if(num>=0xFFFF0000&&razr==r32)nrazr=razr=r16; |
||
5507 | |||
5508 | if(reg==AL)op(0x24); |
||
5509 | |||
5510 | op(128); |
||
5511 | |||
5512 | } |
||
5513 | |||
5514 | return TRUE; |
||
5515 | |||
5516 | if(nrazr==r16){ |
||
5517 | |||
5518 | if(reg==AX)op(0x25); |
||
5519 | |||
5520 | op(129); |
||
5521 | |||
5522 | } |
||
5523 | |||
5524 | return TRUE; |
||
5525 | |||
5526 | } |
||
5527 | |||
5528 | (razr==r32&&num==0xfffffffe&&am32)){ |
||
5529 | |||
5530 | op(0x40+reg); |
||
5531 | |||
5532 | setzeroflag=TRUE; |
||
5533 | |||
5534 | } |
||
5535 | |||
5536 | op(0x48+reg); |
||
5537 | |||
5538 | setzeroflag=TRUE; |
||
5539 | |||
5540 | } |
||
5541 | |||
5542 | if(short_ok(num,razr/2-1)){ |
||
5543 | |||
5544 | op(0x83); |
||
5545 | |||
5546 | op(num); |
||
5547 | |||
5548 | return TRUE; |
||
5549 | |||
5550 | return FALSE; |
||
5551 | |||
5552 | |||
5553 | |||
5554 | { |
||
5555 | |||
5556 | int vop=0,i=0,sign=0; |
||
5557 | |||
5558 | int rrettype=tk_byte; |
||
5559 | |||
5560 | char *ofsstr=NULL; |
||
5561 | |||
5562 | switch(tok){ |
||
5563 | |||
5564 | if(!((tok2==tk_reg||tok2==tk_reg32||tok2==tk_beg)&&ScanTok3()==terminater)){ |
||
5565 | |||
5566 | } |
||
5567 | |||
5568 | nexttok(); |
||
5569 | |||
5570 | waralreadinitreg(begs[itok.number],begs[beg]); |
||
5571 | |||
5572 | } |
||
5573 | |||
5574 | int retreg; |
||
5575 | |||
5576 | GetEndLex(terminater); |
||
5577 | |||
5578 | itok.number=retreg==SKIPREG?beg:retreg; |
||
5579 | |||
5580 | } |
||
5581 | |||
5582 | nexttok(); |
||
5583 | |||
5584 | while(tok==tk_mult){ |
||
5585 | |||
5586 | numpointr++; |
||
5587 | |||
5588 | if(numpointr>itok.npointr)unuseableinput(); |
||
5589 | |||
5590 | int hnumber=MultiAssign(r8,(beg>3?beg-4:beg),numpointr); |
||
5591 | |||
5592 | free(ofsstr); |
||
5593 | |||
5594 | } |
||
5595 | |||
5596 | op(0x88); |
||
5597 | |||
5598 | } |
||
5599 | |||
5600 | if(ofsstr){ |
||
5601 | |||
5602 | free(ofsstr); |
||
5603 | |||
5604 | break; |
||
5605 | |||
5606 | if(tok==tk_pointer)cpointr(am32==TRUE?(beg>3?beg-4:beg):BX,numpointr); |
||
5607 | |||
5608 | if(beg==AL){ |
||
5609 | |||
5610 | else if(rrettype==tk_int||rrettype==tk_word)rettype=do_e_axmath(sign,r16,&ofsstr); |
||
5611 | |||
5612 | next=0; |
||
5613 | |||
5614 | else{ |
||
5615 | |||
5616 | rettype=getintobeg(beg,&ofsstr); |
||
5617 | |||
5618 | dobegmath(beg); |
||
5619 | |||
5620 | } |
||
5621 | |||
5622 | else{ |
||
5623 | |||
5624 | else next=r32; |
||
5625 | |||
5626 | } |
||
5627 | |||
5628 | } |
||
5629 | |||
5630 | IDZToReg(ofsstr,beg,r8); |
||
5631 | |||
5632 | } |
||
5633 | |||
5634 | case tk_plusplus: op(0xFE); op(0xC0+beg); |
||
5635 | |||
5636 | break; |
||
5637 | |||
5638 | ClearReg(beg>3?beg%4:beg); |
||
5639 | |||
5640 | case tk_swap: |
||
5641 | |||
5642 | switch(tok){ |
||
5643 | |||
5644 | case tk_bytevar: |
||
5645 | |||
5646 | outseg(&itok,2); |
||
5647 | |||
5648 | op(beg*8+itok.rm); |
||
5649 | |||
5650 | KillVar(itok.name); |
||
5651 | |||
5652 | break; |
||
5653 | |||
5654 | if(beg!=(int)itok.number){ |
||
5655 | |||
5656 | op(0x86); |
||
5657 | |||
5658 | } |
||
5659 | |||
5660 | } |
||
5661 | |||
5662 | default: swaperror(); break; |
||
5663 | |||
5664 | break; |
||
5665 | |||
5666 | case tk_minusequals: vop+=0x08; |
||
5667 | |||
5668 | case tk_orequals: vop+=0x08; |
||
5669 | |||
5670 | ClearReg(beg>3?beg%4:beg); |
||
5671 | |||
5672 | inptr2--; |
||
5673 | |||
5674 | if(tok==tk_plusequals)tok=tk_plus; |
||
5675 | |||
5676 | if(beg==AL)doalmath2(0); |
||
5677 | |||
5678 | next=0; |
||
5679 | |||
5680 | } |
||
5681 | |||
5682 | if(itok2.type==tp_opperand&&tok!=tk_number){ |
||
5683 | |||
5684 | getintobeg(CL,&ofsstr); |
||
5685 | |||
5686 | sign=CL; //sign исп как пром регистр |
||
5687 | |||
5688 | else{ |
||
5689 | |||
5690 | sign=EAX; |
||
5691 | |||
5692 | warningreg(begs[sign]); |
||
5693 | |||
5694 | op(0xC0+beg+sign*8); |
||
5695 | |||
5696 | break; |
||
5697 | |||
5698 | switch(tok){ |
||
5699 | |||
5700 | i=doconstlongmath(); |
||
5701 | |||
5702 | if(i==0&&(vop==0||vop==0x28||vop==8))break; |
||
5703 | |||
5704 | if(beg==AL)op(0x04+vop); |
||
5705 | |||
5706 | op(0x80); |
||
5707 | |||
5708 | } |
||
5709 | |||
5710 | break; |
||
5711 | |||
5712 | i+=4; |
||
5713 | |||
5714 | case tk_dwordvar: |
||
5715 | |||
5716 | case tk_wordvar: |
||
5717 | |||
5718 | i++; |
||
5719 | |||
5720 | case tk_bytevar: |
||
5721 | |||
5722 | CheckAllMassiv(bufrm,i,&strinf); |
||
5723 | |||
5724 | op(0x02+vop); |
||
5725 | |||
5726 | outaddress(&itok); |
||
5727 | |||
5728 | case tk_beg: |
||
5729 | |||
5730 | op(0xC0+beg+(unsigned int)itok.number*8); |
||
5731 | |||
5732 | case tk_proc: |
||
5733 | |||
5734 | case tk_undefproc: |
||
5735 | |||
5736 | case tk_ID: |
||
5737 | |||
5738 | op66(r16); |
||
5739 | |||
5740 | op(0x50+i); |
||
5741 | |||
5742 | warningreg(regs[0][i]); |
||
5743 | |||
5744 | if(itok2.type==tp_opperand){ |
||
5745 | |||
5746 | doalmath2(0); |
||
5747 | |||
5748 | } |
||
5749 | |||
5750 | op66(r16); |
||
5751 | |||
5752 | if(i!=AX){ |
||
5753 | |||
5754 | op(0xc0+beg); |
||
5755 | |||
5756 | else{ |
||
5757 | |||
5758 | op(0x86); |
||
5759 | |||
5760 | } |
||
5761 | |||
5762 | op(0xc0+CL*8+beg); |
||
5763 | |||
5764 | break; |
||
5765 | |||
5766 | if((unsigned int)itok.number |
||
5767 | |||
5768 | op(0xC0+beg+(unsigned int)itok.number*8); |
||
5769 | |||
5770 | else begworderror(); |
||
5771 | |||
5772 | case tk_seg: begworderror(); break; |
||
5773 | |||
5774 | } |
||
5775 | |||
5776 | case tk_rrequals: vop+=0x08; |
||
5777 | |||
5778 | getoperand(am32==TRUE?ECX:BX); |
||
5779 | |||
5780 | if(itok2.type==tp_stopper&&tok==tk_number){ |
||
5781 | |||
5782 | op(0xD0); op(0xE0+beg+vop); |
||
5783 | |||
5784 | else if((unsigned int)itok.number!=0){ |
||
5785 | |||
5786 | else{ |
||
5787 | |||
5788 | op(0xe0+beg+vop); |
||
5789 | |||
5790 | } |
||
5791 | |||
5792 | } |
||
5793 | |||
5794 | shiftbeg: |
||
5795 | |||
5796 | if(itok2.type==tp_stopper&&tok==tk_beg&&itok.number==CL){ |
||
5797 | |||
5798 | } |
||
5799 | |||
5800 | ClearReg(CL); |
||
5801 | |||
5802 | dobegmath(CL); |
||
5803 | |||
5804 | warningreg(begs[1]); |
||
5805 | |||
5806 | } |
||
5807 | |||
5808 | else regshifterror(); |
||
5809 | |||
5810 | break; |
||
5811 | |||
5812 | } |
||
5813 | |||
5814 | if(terminater==tk_semicolon)seminext(); |
||
5815 | |||
5816 | } |
||
5817 | |||
5818 | void doseg(int seg) |
||
5819 | |||
5820 | unsigned char next=1; |
||
5821 | |||
5822 | char *ofsstr=NULL; |
||
5823 | |||
5824 | if(seg==FS||seg==GS)if(cpu<3)cpu=3; |
||
5825 | |||
5826 | nexttok(); |
||
5827 | |||
5828 | if(tok==tk_assign){ |
||
5829 | |||
5830 | while(tok==tk_mult){ |
||
5831 | |||
5832 | numpointr++; |
||
5833 | |||
5834 | if(numpointr>itok.npointr)unuseableinput(); |
||
5835 | |||
5836 | itok.number=MultiAssign(r16,USEALLREG,numpointr); |
||
5837 | |||
5838 | free(ofsstr); |
||
5839 | |||
5840 | } |
||
5841 | |||
5842 | } |
||
5843 | |||
5844 | if(itok2.type!=tp_opperand){ |
||
5845 | |||
5846 | case tk_reg: |
||
5847 | |||
5848 | op(0x8E); |
||
5849 | |||
5850 | break; |
||
5851 | |||
5852 | case tk_wordvar: |
||
5853 | |||
5854 | case tk_dwordvar: |
||
5855 | |||
5856 | CheckAllMassiv(bufrm,2,&strinf); |
||
5857 | |||
5858 | outseg(&itok,2); |
||
5859 | |||
5860 | op(seg*8+itok.rm); |
||
5861 | |||
5862 | break; |
||
5863 | |||
5864 | if(optimizespeed==FALSE||(regoverstack&&chip>2)){ |
||
5865 | |||
5866 | PopSeg(seg); |
||
5867 | |||
5868 | } |
||
5869 | |||
5870 | case tk_number: |
||
5871 | |||
5872 | // op66(r16); |
||
5873 | |||
5874 | op(0x6A); |
||
5875 | |||
5876 | } |
||
5877 | |||
5878 | op(0x68); |
||
5879 | |||
5880 | if(am32)outdword(itok.number); |
||
5881 | |||
5882 | } |
||
5883 | |||
5884 | if(cpu<2)cpu=2; |
||
5885 | |||
5886 | } |
||
5887 | |||
5888 | default: goto segax; |
||
5889 | |||
5890 | } |
||
5891 | |||
5892 | segax: |
||
5893 | |||
5894 | op(0x8E); /* MOV SEG,AX */ |
||
5895 | |||
5896 | next=0; |
||
5897 | |||
5898 | } |
||
5899 | |||
5900 | getoperand(); |
||
5901 | |||
5902 | case tk_intvar: |
||
5903 | |||
5904 | KillVar(itok.name); |
||
5905 | |||
5906 | op(0x8C); |
||
5907 | |||
5908 | CheckAllMassiv(bufrm,2,&strinf); |
||
5909 | |||
5910 | outseg(&itok,2); |
||
5911 | |||
5912 | op(itok.rm); |
||
5913 | |||
5914 | op66(r16); |
||
5915 | |||
5916 | op(0xC0+seg*8); /* MOV seg,AX */ |
||
5917 | |||
5918 | case tk_seg: |
||
5919 | |||
5920 | PushSeg(seg); |
||
5921 | |||
5922 | PopSeg(seg); |
||
5923 | |||
5924 | break; |
||
5925 | |||
5926 | break; |
||
5927 | |||
5928 | } |
||
5929 | |||
5930 | if(next)nextseminext(); |
||
5931 | |||
5932 | } |
||
5933 | |||
5934 | void PushSeg(int seg) |
||
5935 | |||
5936 | switch(seg){ |
||
5937 | |||
5938 | case CS: op(0x0E); break; |
||
5939 | |||
5940 | case ES: op(0x06); break; |
||
5941 | |||
5942 | case GS: outword(0xA80F); if(cpu<3)cpu=3; break; |
||
5943 | |||
5944 | } |
||
5945 | |||
5946 | void PopSeg(int seg) |
||
5947 | |||
5948 | switch(seg){ |
||
5949 | |||
5950 | case SS: op(0x17); break; |
||
5951 | |||
5952 | case FS: outword(0xA10F); if(cpu<3)cpu=3; break; |
||
5953 | |||
5954 | } |
||
5955 | |||
5956 | |||
5957 | |||
5958 | |||
5959 | |||
5960 | // all other registers preserved |
||
5961 | |||
5962 | int vop,i,optnum,negflag=FALSE; |
||
5963 | |||
5964 | if(negflag){ |
||
5965 | |||
5966 | negflag=FALSE; |
||
5967 | |||
5968 | i=vop=0; |
||
5969 | |||
5970 | #ifdef OPTVARCONST |
||
5971 | |||
5972 | if(tok2==tk_number)calcnumber=TRUE; |
||
5973 | |||
5974 | if(uselea){ |
||
5975 | |||
5976 | if(Reg32ToLea2(reg))continue; //оптимизация сложения 32-битных регистров в LEA |
||
5977 | |||
5978 | else if(Reg16ToLea2(reg))continue; |
||
5979 | |||
5980 | } |
||
5981 | |||
5982 | switch(tok){ |
||
5983 | |||
5984 | case tk_minus: vop+=0x08; |
||
5985 | |||
5986 | case tk_or: vop+=0x08; |
||
5987 | |||
5988 | if(optnum==FALSE)getoperand(reg==BX?SI:BX); |
||
5989 | |||
5990 | switch(tok){ |
||
5991 | |||
5992 | if((itok.flag&f_reloc)==0&&optnumadd(itok.number,reg,razr,vop))break; |
||
5993 | |||
5994 | case tk_undefofs: |
||
5995 | |||
5996 | op(0x81); |
||
5997 | |||
5998 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
5999 | |||
6000 | else if((itok.flag&f_reloc)!=0)AddReloc(); |
||
6001 | |||
6002 | break; |
||
6003 | |||
6004 | op66(razr); |
||
6005 | |||
6006 | op(0xC0+vop+reg); |
||
6007 | |||
6008 | break; |
||
6009 | |||
6010 | i=4; |
||
6011 | |||
6012 | Float2reg32(EAX,i); |
||
6013 | |||
6014 | warningreg(regs[1][EAX]); |
||
6015 | |||
6016 | case tk_bits: |
||
6017 | |||
6018 | i=itok.bit.siz+itok.bit.ofs; |
||
6019 | |||
6020 | if(i<=32)vops=r32; |
||
6021 | |||
6022 | if(vops |
||
6023 | |||
6024 | if(reg==CX)reg2s=DI; |
||
6025 | |||
6026 | if(vops==r64)vops=r32; |
||
6027 | |||
6028 | itok.number=reg2s; |
||
6029 | |||
6030 | case tk_reg: |
||
6031 | |||
6032 | op66(razr); |
||
6033 | |||
6034 | if(itok.number==reg){ |
||
6035 | |||
6036 | itok.number=EAX; |
||
6037 | |||
6038 | else op(0xC0+itok.number*9); |
||
6039 | |||
6040 | } |
||
6041 | |||
6042 | defreg32: |
||
6043 | |||
6044 | op(0x01+vop); |
||
6045 | |||
6046 | break; |
||
6047 | |||
6048 | case tk_longvar: |
||
6049 | |||
6050 | i=4; |
||
6051 | |||
6052 | case tk_intvar: |
||
6053 | |||
6054 | if(razr==r32)goto addchar; |
||
6055 | |||
6056 | wordvar: |
||
6057 | |||
6058 | op66(razr); |
||
6059 | |||
6060 | op(0x03+vop); |
||
6061 | |||
6062 | outaddress(&itok); |
||
6063 | |||
6064 | case tk_charvar: |
||
6065 | |||
6066 | case tk_bytevar: |
||
6067 | |||
6068 | case tk_rmnumber: |
||
6069 | |||
6070 | SINFO wstr; |
||
6071 | |||
6072 | char *wbuf; |
||
6073 | |||
6074 | strinf.bufstr=NULL; |
||
6075 | |||
6076 | bufrm=NULL; |
||
6077 | |||
6078 | getinto_e_ax(sign,tok,&wtok,wbuf,&wstr,razr); |
||
6079 | |||
6080 | case tk_ID: |
||
6081 | |||
6082 | case tk_proc: |
||
6083 | |||
6084 | case tk_undefproc: |
||
6085 | |||
6086 | unsigned char oaddstack; |
||
6087 | |||
6088 | op66(razr); |
||
6089 | |||
6090 | } |
||
6091 | |||
6092 | oaddstack=addstack; |
||
6093 | |||
6094 | procdo(razr==r16?(sign==0?tk_word:tk_int):(sign==0?tk_dword:tk_long)); |
||
6095 | |||
6096 | addESP-=razr==r16?2:4; |
||
6097 | |||
6098 | op66(razr); |
||
6099 | |||
6100 | } |
||
6101 | |||
6102 | op66(razr); |
||
6103 | |||
6104 | op(0xc0+reg); |
||
6105 | |||
6106 | break; |
||
6107 | |||
6108 | } |
||
6109 | |||
6110 | case tk_xorminus: vop+=0x10; |
||
6111 | |||
6112 | case tk_orminus: vop+=0x08; |
||
6113 | |||
6114 | switch(tok){ |
||
6115 | |||
6116 | itok.number=-itok.number; |
||
6117 | |||
6118 | op(0x81); |
||
6119 | |||
6120 | if((itok.flag&f_reloc)!=0)AddReloc(); |
||
6121 | |||
6122 | break; |
||
6123 | |||
6124 | case tk_id: |
||
6125 | |||
6126 | case tk_apiproc: |
||
6127 | |||
6128 | case tk_declare: |
||
6129 | |||
6130 | i=EAX; |
||
6131 | |||
6132 | |||
6133 | |||
6134 | } |
||
6135 | |||
6136 | default: |
||
6137 | |||
6138 | i=EAX; |
||
6139 | |||
6140 | wstr=strinf; |
||
6141 | |||
6142 | ITOK wtok; |
||
6143 | |||
6144 | wbuf=bufrm; |
||
6145 | |||
6146 | wtok=itok; |
||
6147 | |||
6148 | } |
||
6149 | |||
6150 | i=ECX; |
||
6151 | |||
6152 | } |
||
6153 | |||
6154 | NegReg(razr,i); |
||
6155 | |||
6156 | op(vop+1); /* opt AX,CX */ |
||
6157 | |||
6158 | warningreg(regs[razr/2-1][i]); |
||
6159 | |||
6160 | break; |
||
6161 | |||
6162 | break; |
||
6163 | |||
6164 | if(reg==ECX){ |
||
6165 | |||
6166 | break; |
||
6167 | |||
6168 | tok=tk_minus; |
||
6169 | |||
6170 | op66(razr); |
||
6171 | |||
6172 | op(0xE8+reg); // SHL xXX,CL |
||
6173 | |||
6174 | continue; |
||
6175 | |||
6176 | getoperand(am32==TRUE?ECX:(reg==BX?SI:BX)); |
||
6177 | |||
6178 | else continue; |
||
6179 | |||
6180 | case tk_llminus: |
||
6181 | |||
6182 | regmathoperror(); |
||
6183 | |||
6184 | } |
||
6185 | |||
6186 | goto llshift; |
||
6187 | |||
6188 | getoperand(am32==TRUE?ECX:(reg==BX?SI:BX)); |
||
6189 | |||
6190 | if(chip<2&®==CX){ |
||
6191 | |||
6192 | break; |
||
6193 | |||
6194 | lshiftmul(itok.number,razr,reg); |
||
6195 | |||
6196 | else if(reg!=ECX&&(tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==CL){ |
||
6197 | |||
6198 | op(0xD3); |
||
6199 | |||
6200 | } |
||
6201 | |||
6202 | |||
6203 | |||
6204 | op66(razr); |
||
6205 | |||
6206 | op(0xE0+reg); // SHL xXX,CL |
||
6207 | |||
6208 | continue; |
||
6209 | |||
6210 | else regmathoperror(); |
||
6211 | |||
6212 | case tk_multminus: negflag=TRUE; |
||
6213 | |||
6214 | if(optnum==FALSE)getoperand(reg==BX?SI:BX); |
||
6215 | |||
6216 | if(negflag&&tok==tk_number){ |
||
6217 | |||
6218 | negflag=FALSE; |
||
6219 | |||
6220 | if(MulReg(reg,razr)==0)continue; |
||
6221 | |||
6222 | case tk_modminus: negflag=1; |
||
6223 | |||
6224 | vop=1; |
||
6225 | |||
6226 | case tk_divminus: negflag=1; |
||
6227 | |||
6228 | divcalc: |
||
6229 | |||
6230 | else tok=tk_number; |
||
6231 | |||
6232 | itok.number=-itok.number; |
||
6233 | |||
6234 | } |
||
6235 | |||
6236 | if(vop){ //mod |
||
6237 | |||
6238 | if(itok.number==0){ |
||
6239 | |||
6240 | } |
||
6241 | |||
6242 | op66(razr); |
||
6243 | |||
6244 | op(0xE0+reg); //and reg,num-1 |
||
6245 | |||
6246 | } |
||
6247 | |||
6248 | op66(razr); |
||
6249 | |||
6250 | op(0xE0+reg); //and reg,num-1 |
||
6251 | |||
6252 | } |
||
6253 | |||
6254 | else{ |
||
6255 | |||
6256 | if(chip<2&&razr==r16){ |
||
6257 | |||
6258 | op(0xB1); op(i); /* MOV CL,num */ |
||
6259 | |||
6260 | op(0xE8+reg); // SHR reg,CL |
||
6261 | |||
6262 | } |
||
6263 | |||
6264 | op66(razr); |
||
6265 | |||
6266 | op(0xE8+reg); // SHR reg,num |
||
6267 | |||
6268 | } |
||
6269 | |||
6270 | } |
||
6271 | |||
6272 | } |
||
6273 | |||
6274 | op66(razr); |
||
6275 | |||
6276 | } |
||
6277 | |||
6278 | if(itok.type!=tp_stopper){ |
||
6279 | |||
6280 | op66(razr); |
||
6281 | |||
6282 | else op(0x92); //xchg ax,dx |
||
6283 | |||
6284 | do_e_axmath2(0,razr,0); |
||
6285 | |||
6286 | else if(vop==1){ |
||
6287 | |||
6288 | op66(razr); |
||
6289 | |||
6290 | op(128+64+EDX*8+reg); |
||
6291 | |||
6292 | warningreg(regs[razr/2-1][EAX]); |
||
6293 | |||
6294 | } |
||
6295 | |||
6296 | if(optimizespeed){ |
||
6297 | |||
6298 | op(128+64+EAX*8+reg); |
||
6299 | |||
6300 | else op(0x90+reg); //xchg AX,reg |
||
6301 | |||
6302 | continue; |
||
6303 | |||
6304 | } |
||
6305 | |||
6306 | ClearReg(reg); |
||
6307 | |||
6308 | } |
||
6309 | |||
6310 | ClearReg(reg); |
||
6311 | |||
6312 | } |
||
6313 | |||
6314 | void dobegmath(int beg) // math done is on all begs except AL |
||
6315 | |||
6316 | { |
||
6317 | |||
6318 | while(itok.type!=tp_stopper&&tok!=tk_eof){ |
||
6319 | |||
6320 | i=0; |
||
6321 | |||
6322 | if(tok2>=tk_charvar&&tok2<=tk_doublevar&&itok2.npointr==0){ |
||
6323 | |||
6324 | tok2=tk_number; |
||
6325 | |||
6326 | } |
||
6327 | |||
6328 | #endif |
||
6329 | |||
6330 | int oldtok=tok; |
||
6331 | |||
6332 | case tk_xor: vop+=0x08; |
||
6333 | |||
6334 | case tk_and: vop+=0x18; |
||
6335 | |||
6336 | case tk_plus: |
||
6337 | |||
6338 | else{ |
||
6339 | |||
6340 | optnum=FALSE; |
||
6341 | |||
6342 | switch(tok){ |
||
6343 | |||
6344 | if(itok.number==0&&oldtok!=tk_and)break; |
||
6345 | |||
6346 | if(oldtok==tk_plus){ |
||
6347 | |||
6348 | op(0xC0+beg); |
||
6349 | |||
6350 | } |
||
6351 | |||
6352 | op(0xFE); |
||
6353 | |||
6354 | break; |
||
6355 | |||
6356 | } |
||
6357 | |||
6358 | if(oldtok==tk_minus){ |
||
6359 | |||
6360 | op(0xC0+beg); |
||
6361 | |||
6362 | } |
||
6363 | |||
6364 | op(0xFE); |
||
6365 | |||
6366 | break; |
||
6367 | |||
6368 | } |
||
6369 | |||
6370 | op(0xC0+vop+beg); |
||
6371 | |||
6372 | break; |
||
6373 | |||
6374 | int vops,reg2s; |
||
6375 | |||
6376 | if(i<=64)vops=r64; |
||
6377 | |||
6378 | if(i<=16)vops=r16; |
||
6379 | |||
6380 | reg2s=CL; |
||
6381 | |||
6382 | bits2reg(reg2s,vops); |
||
6383 | |||
6384 | warningreg(vops==r8?begs[reg2s]:regs[vops/2-1][reg2s]); |
||
6385 | |||
6386 | case tk_beg: |
||
6387 | |||
6388 | op(0xC0+beg+(unsigned int)itok.number*8); |
||
6389 | |||
6390 | case tk_qwordvar: |
||
6391 | |||
6392 | case tk_longvar: |
||
6393 | |||
6394 | i+=2; |
||
6395 | |||
6396 | case tk_wordvar: |
||
6397 | |||
6398 | case tk_bytevar: |
||
6399 | |||
6400 | i++; |
||
6401 | |||
6402 | outseg(&itok,2); |
||
6403 | |||
6404 | op(beg*8+itok.rm); |
||
6405 | |||
6406 | break; |
||
6407 | |||
6408 | case tk_reg: |
||
6409 | |||
6410 | case tk_ID: |
||
6411 | |||
6412 | case tk_proc: |
||
6413 | |||
6414 | case tk_undefproc:// begcallerror(); break; |
||
6415 | |||
6416 | procdo(tk_byte); |
||
6417 | |||
6418 | op(0x00+vop); |
||
6419 | |||
6420 | } |
||
6421 | |||
6422 | default: valueexpected(); break; |
||
6423 | |||
6424 | break; |
||
6425 | |||
6426 | case tk_andminus: vop+=0x18; |
||
6427 | |||
6428 | getoperand(beg==BL||beg==BH?SI:BX); |
||
6429 | |||
6430 | itok.number=-itok.number; |
||
6431 | |||
6432 | op(0xC0+vop +beg); |
||
6433 | |||
6434 | } |
||
6435 | |||
6436 | break; |
||
6437 | |||
6438 | vop=8; |
||
6439 | |||
6440 | nexttok(); |
||
6441 | |||
6442 | if((unsigned int)itok.number==1){ |
||
6443 | |||
6444 | op(2); |
||
6445 | |||
6446 | } |
||
6447 | |||
6448 | op(0xD0); op(0xE8+beg); /* SHR reg,1 */ |
||
6449 | |||
6450 | } |
||
6451 | |||
6452 | if(chip<2)begmathoperror(); |
||
6453 | |||
6454 | op(0xc0); |
||
6455 | |||
6456 | op((unsigned int)itok.number); |
||
6457 | |||
6458 | } |
||
6459 | |||
6460 | } |
||
6461 | |||
6462 | op(0xD2); |
||
6463 | |||
6464 | } |
||
6465 | |||
6466 | break; |
||
6467 | |||
6468 | case tk_mult: |
||
6469 | |||
6470 | else{ |
||
6471 | |||
6472 | optnum=FALSE; |
||
6473 | |||
6474 | if(negflag&&tok==tk_number){ |
||
6475 | |||
6476 | negflag=FALSE; |
||
6477 | |||
6478 | switch(tok){ |
||
6479 | |||
6480 | itok.number&=255; |
||
6481 | |||
6482 | case 0: // beg * 0 = MOV beg,0 |
||
6483 | |||
6484 | case 1: break; //beg*1=beg |
||
6485 | |||
6486 | op(0); |
||
6487 | |||
6488 | break; |
||
6489 | |||
6490 | vop=caselong(itok.number); |
||
6491 | |||
6492 | if(chip<1)begmathoperror(); |
||
6493 | |||
6494 | op(0xc0); |
||
6495 | |||
6496 | op(vop); |
||
6497 | |||
6498 | } |
||
6499 | |||
6500 | else begmathoperror(); |
||
6501 | |||
6502 | break; |
||
6503 | |||
6504 | } |
||
6505 | |||
6506 | case tk_divminus: |
||
6507 | |||
6508 | case tk_div: |
||
6509 | |||
6510 | case tk_rrminus: |
||
6511 | |||
6512 | begmathoperror(); break; |
||
6513 | |||
6514 | } |
||
6515 | |||
6516 | calcnumber=FALSE; |
||
6517 | |||
6518 | nexttok(); |
||
6519 | |||
6520 | } |
||
6521 | |||
6522 | |||
6523 | |||
6524 | |||
6525 | |||
6526 | { |
||
6527 | |||
6528 | int swap=0,oflag=0; |
||
6529 | |||
6530 | int reg1=idxregs[0],reg2=idxregs[1]; |
||
6531 | |||
6532 | int loop=0,otok; |
||
6533 | |||
6534 | if(!am32){ |
||
6535 | |||
6536 | reg1=reg; |
||
6537 | |||
6538 | } |
||
6539 | |||
6540 | else{ |
||
6541 | |||
6542 | if(reg==idxregs[1])reg2=idxregs[0]; |
||
6543 | |||
6544 | if(tok==tk_minus){ |
||
6545 | |||
6546 | negflag=1; |
||
6547 | |||
6548 | } |
||
6549 | |||
6550 | loopswitch: |
||
6551 | |||
6552 | if(uselea){ |
||
6553 | |||
6554 | if(cpu<3)cpu=3; |
||
6555 | |||
6556 | return tk_reg; |
||
6557 | |||
6558 | } |
||
6559 | |||
6560 | if(Reg16ToLea(reg)){ |
||
6561 | |||
6562 | } |
||
6563 | |||
6564 | loopswitch1: |
||
6565 | |||
6566 | #ifdef OPTVARCONST |
||
6567 | |||
6568 | if(tok==tk_number)calcnumber=TRUE; |
||
6569 | |||
6570 | otok=tok; |
||
6571 | |||
6572 | switch(tok){ |
||
6573 | |||
6574 | if(useloop==FALSE)MovRegNum(razr,itok.flag&f_reloc,itok.number,reg); |
||
6575 | |||
6576 | holdnumber=CalcNumber(sign); |
||
6577 | |||
6578 | else oflag^=postnumflag; |
||
6579 | |||
6580 | if(tok==tk_mult){ |
||
6581 | |||
6582 | swap=1; |
||
6583 | |||
6584 | } |
||
6585 | |||
6586 | nexttok(); |
||
6587 | |||
6588 | goto loopswitch1; |
||
6589 | |||
6590 | MovRegNum(razr,oflag&f_reloc,holdnumber,reg); |
||
6591 | |||
6592 | } |
||
6593 | |||
6594 | case tk_postnumber: |
||
6595 | |||
6596 | if(!swap){ |
||
6597 | |||
6598 | op(0xB8+reg); /* MOV AX,# */ |
||
6599 | |||
6600 | } |
||
6601 | |||
6602 | AddUndefOff(2,itok.name); |
||
6603 | |||
6604 | // itok.flag=0; //new 07.07.04 23:57 |
||
6605 | |||
6606 | else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
6607 | |||
6608 | else{ |
||
6609 | |||
6610 | holdnumber+=doconstdwordmath(); |
||
6611 | |||
6612 | if(loop==0)oflag=postnumflag; |
||
6613 | |||
6614 | loop++; |
||
6615 | |||
6616 | if(tok==tk_plus&&tok2==tk_postnumber){ |
||
6617 | |||
6618 | goto loopswitch1; |
||
6619 | |||
6620 | swap=0; |
||
6621 | |||
6622 | } |
||
6623 | |||
6624 | if(razr==r16)outword(holdnumber); |
||
6625 | |||
6626 | ClearReg(reg); |
||
6627 | |||
6628 | case tk_apioffset: |
||
6629 | |||
6630 | op(0xB8+reg); /* MOV AX,# */ |
||
6631 | |||
6632 | ClearReg(reg); |
||
6633 | |||
6634 | case tk_rmnumber: |
||
6635 | |||
6636 | if((am32&&itok.rm==reg&®!=EBP&®!=ESP)||(am32==0&®==itok.rm&& |
||
6637 | |||
6638 | op66(razr); |
||
6639 | |||
6640 | if(itok.post==0)outseg(&itok,2); |
||
6641 | |||
6642 | op(reg*8+itok.rm); |
||
6643 | |||
6644 | if((itok.flag&f_extern)==0){ |
||
6645 | |||
6646 | if(am32&&itok.rm==rm_sib)outptr++; |
||
6647 | |||
6648 | outptr=ooutptr; |
||
6649 | |||
6650 | else setwordext(&itok.number); |
||
6651 | |||
6652 | if(useloop==FALSE)outaddress(&itok); |
||
6653 | |||
6654 | ITOK oitok; |
||
6655 | |||
6656 | tok=tk_number; |
||
6657 | |||
6658 | oitok.number=doconstdwordmath(); |
||
6659 | |||
6660 | next=0; |
||
6661 | |||
6662 | ClearReg(reg); |
||
6663 | |||
6664 | case tk_qwordvar: |
||
6665 | |||
6666 | case tk_longvar: |
||
6667 | |||
6668 | i+=4; |
||
6669 | |||
6670 | CheckAllMassiv(bufrm,i,&strinf,&itok,reg1,reg2); |
||
6671 | |||
6672 | outseg(&itok,2); |
||
6673 | |||
6674 | op(reg*8+itok.rm); |
||
6675 | |||
6676 | ClearReg(reg); |
||
6677 | |||
6678 | case tk_intvar: |
||
6679 | |||
6680 | i=2; |
||
6681 | |||
6682 | CheckAllMassiv(bufrm,2,&strinf,&itok,reg1,reg2); |
||
6683 | |||
6684 | ZeroReg(reg,r32); |
||
6685 | |||
6686 | outseg(&itok,2); //mov reg,var |
||
6687 | |||
6688 | } |
||
6689 | |||
6690 | op66(r32); |
||
6691 | |||
6692 | op(0x0F); op(tok==tk_wordvar?0xB7:0xBF); |
||
6693 | |||
6694 | op(reg*8+itok.rm); |
||
6695 | |||
6696 | ClearReg(reg); |
||
6697 | |||
6698 | case tk_doublevar: |
||
6699 | |||
6700 | case tk_floatvar: |
||
6701 | |||
6702 | ClearReg(reg); |
||
6703 | |||
6704 | case tk_bytevar: |
||
6705 | |||
6706 | if(chip>2||razr==r32){ |
||
6707 | |||
6708 | if(reg<=EBX&&tok==tk_bytevar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ |
||
6709 | |||
6710 | outseg(&itok,2); |
||
6711 | |||
6712 | } |
||
6713 | |||
6714 | op66(razr); |
||
6715 | |||
6716 | op(0xf); |
||
6717 | |||
6718 | else op(0xbe); |
||
6719 | |||
6720 | op(reg*8+itok.rm); // MOVZX regL,[byte] |
||
6721 | |||
6722 | ClearReg(reg); |
||
6723 | |||
6724 | } |
||
6725 | |||
6726 | if(reg==AX&&itok.rm==rm_d16&&itok.sib==CODE16){ |
||
6727 | |||
6728 | op(0xA0); // MOV AL,[byte] |
||
6729 | |||
6730 | } |
||
6731 | |||
6732 | CheckAllMassiv(bufrm,1,&strinf,&itok,reg1,reg2); |
||
6733 | |||
6734 | op(0x8A); |
||
6735 | |||
6736 | outaddress(&itok); |
||
6737 | |||
6738 | ClearReg(reg); |
||
6739 | |||
6740 | } |
||
6741 | |||
6742 | break; |
||
6743 | |||
6744 | if(razr==r32){ |
||
6745 | |||
6746 | reg1=itok.number; |
||
6747 | |||
6748 | param[0]=0; |
||
6749 | |||
6750 | else doparams(); |
||
6751 | |||
6752 | op(0xFF); |
||
6753 | |||
6754 | itok.number=0; |
||
6755 | |||
6756 | #ifdef OPTVARCONST |
||
6757 | |||
6758 | #endif |
||
6759 | |||
6760 | if(optimizespeed&&chip>3&&chip<7&®!=(int)itok.number){ |
||
6761 | |||
6762 | op(0x89); |
||
6763 | |||
6764 | } |
||
6765 | |||
6766 | op66(r32); |
||
6767 | |||
6768 | op(0xC0+reg*8+(unsigned int)itok.number); |
||
6769 | |||
6770 | RegToReg(reg,itok.number,r32); |
||
6771 | |||
6772 | } |
||
6773 | |||
6774 | if(tok2==tk_openbracket){ //вызов процедуры по адресу в регистре |
||
6775 | |||
6776 | |||
6777 | |||
6778 | param[0]=0; |
||
6779 | |||
6780 | else doparams(); |
||
6781 | |||
6782 | op(0xFF); |
||
6783 | |||
6784 | itok.number=0; |
||
6785 | |||
6786 | #ifdef OPTVARCONST |
||
6787 | |||
6788 | #endif |
||
6789 | |||
6790 | if(reg!=(int)itok.number){ |
||
6791 | |||
6792 | op(0x89); |
||
6793 | |||
6794 | RegToReg(reg,itok.number,r32); |
||
6795 | |||
6796 | break; |
||
6797 | |||
6798 | int vops; |
||
6799 | |||
6800 | |||
6801 | |||
6802 | if(i<=16)vops=r16; |
||
6803 | |||
6804 | break; |
||
6805 | |||
6806 | op66(razr); |
||
6807 | |||
6808 | op(0xC0+reg+(unsigned int)itok.number*8); |
||
6809 | |||
6810 | break; |
||
6811 | |||
6812 | if(chip>2||razr==r32){ |
||
6813 | |||
6814 | ZeroReg(reg,razr); |
||
6815 | |||
6816 | op(0xC0+reg+(unsigned int)itok.number*8); // MOV regL,beg |
||
6817 | |||
6818 | else{ |
||
6819 | |||
6820 | outword(0xb60f); |
||
6821 | |||
6822 | } |
||
6823 | |||
6824 | |||
6825 | |||
6826 | op(0x88); op(0xC0+reg+(unsigned int)itok.number*8); // MOV regL,beg |
||
6827 | |||
6828 | } |
||
6829 | |||
6830 | break; |
||
6831 | |||
6832 | getoperand(am32==FALSE?BX:reg); |
||
6833 | |||
6834 | case tk_ID: |
||
6835 | |||
6836 | case tk_proc: |
||
6837 | |||
6838 | case tk_undefproc: |
||
6839 | |||
6840 | if(itok.flag&f_retproc)rettype=(itok.flag&f_retproc)/256+tk_overflowflag-1; |
||
6841 | |||
6842 | itok.number=0; |
||
6843 | |||
6844 | if(*ofsstr!=NULL){ |
||
6845 | |||
6846 | ofsstr=NULL; |
||
6847 | |||
6848 | // printf("tok=%d num=%d tok2=%d\n",tok,itok.number,tok2); |
||
6849 | |||
6850 | // break; |
||
6851 | |||
6852 | op66(razr); |
||
6853 | |||
6854 | if(razr==r16){ |
||
6855 | |||
6856 | outword(addpoststring()); |
||
6857 | |||
6858 | else outdword(addpoststring()); |
||
6859 | |||
6860 | break; |
||
6861 | |||
6862 | } |
||
6863 | |||
6864 | calcnumber=FALSE; |
||
6865 | |||
6866 | if(negflag)NegReg(razr,reg); |
||
6867 | |||
6868 | negflag=0; |
||
6869 | |||
6870 | ClearReg(reg); |
||
6871 | |||
6872 | if(next)nexttok(); |
||
6873 | |||
6874 | return rettype; |
||
6875 | |||
6876 | |||
6877 | |||
6878 | { |
||
6879 | |||
6880 | int rettype=tk_beg; |
||
6881 | |||
6882 | if(CheckMinusNum()==FALSE){ |
||
6883 | |||
6884 | getoperand(am32==TRUE?(beg>3?beg-4:beg):BX); |
||
6885 | |||
6886 | } |
||
6887 | |||
6888 | if(tok>=tk_charvar&&tok<=tk_doublevar&&itok.npointr==0){ |
||
6889 | |||
6890 | if(CheckConstVar(&itok)){ |
||
6891 | |||
6892 | calcnumber=TRUE; |
||
6893 | |||
6894 | } |
||
6895 | |||
6896 | switch(tok){ |
||
6897 | |||
6898 | op(0xB0+beg); |
||
6899 | |||
6900 | op(i); |
||
6901 | |||
6902 | break; |
||
6903 | |||
6904 | CheckAllMassiv(bufrm,itok.size,&strinf); |
||
6905 | |||
6906 | op67(itok.sib==CODE16?r16:r32); |
||
6907 | |||
6908 | op(0x8D); // LEA reg,[rm] |
||
6909 | |||
6910 | if(itok.post!=0&&itok.post!=UNDEF_OFSET){ |
||
6911 | |||
6912 | unsigned int ooutptr=outptr; |
||
6913 | |||
6914 | setwordpost(&itok); |
||
6915 | |||
6916 | } |
||
6917 | |||
6918 | } |
||
6919 | |||
6920 | ClearReg(beg%4); |
||
6921 | |||
6922 | case tk_postnumber: |
||
6923 | |||
6924 | op(0xB8+beg); |
||
6925 | |||
6926 | outword((unsigned int)itok.number); |
||
6927 | |||
6928 | ClearReg(beg%4); |
||
6929 | |||
6930 | case tk_qwordvar: |
||
6931 | |||
6932 | case tk_longvar: |
||
6933 | |||
6934 | i+=2; |
||
6935 | |||
6936 | case tk_wordvar: |
||
6937 | |||
6938 | case tk_charvar: |
||
6939 | |||
6940 | i++; |
||
6941 | |||
6942 | outseg(&itok,2); |
||
6943 | |||
6944 | op(beg*8+itok.rm); |
||
6945 | |||
6946 | nexttok(); |
||
6947 | |||
6948 | break; |
||
6949 | |||
6950 | i=4; |
||
6951 | |||
6952 | Float2reg32((beg<4?beg:beg-4),i); |
||
6953 | |||
6954 | op(0x88); |
||
6955 | |||
6956 | } |
||
6957 | |||
6958 | ClearReg(beg%4); |
||
6959 | |||
6960 | case tk_bits: |
||
6961 | |||
6962 | i=itok.bit.siz+itok.bit.ofs; |
||
6963 | |||
6964 | if(i<=32)vops=r32; |
||
6965 | |||
6966 | if(i<=8)vops=r8; |
||
6967 | |||
6968 | op66(vops==r64?r32:vops); |
||
6969 | |||
6970 | if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; |
||
6971 | |||
6972 | bits2reg(AX,vops); |
||
6973 | |||
6974 | op(0xC0+beg); |
||
6975 | |||
6976 | addESP-=vops==r16?2:4; |
||
6977 | |||
6978 | } |
||
6979 | |||
6980 | nexttok(); |
||
6981 | |||
6982 | case tk_beg: |
||
6983 | |||
6984 | op(0x88); |
||
6985 | |||
6986 | RegToReg(beg,itok.number,r8); |
||
6987 | |||
6988 | nexttok(); |
||
6989 | |||
6990 | case tk_reg32: |
||
6991 | |||
6992 | if(beg |
||
6993 | |||
6994 | op66(r16); |
||
6995 | |||
6996 | op(0xC0+beg+(unsigned int)itok.number*8); |
||
6997 | |||
6998 | } |
||
6999 | |||
7000 | else begworderror(); |
||
7001 | |||
7002 | break; |
||
7003 | |||
7004 | op66(r16); |
||
7005 | |||
7006 | op(0xC0+beg+(unsigned int)itok.number*8); |
||
7007 | |||
7008 | ClearReg(beg%4); |
||
7009 | |||
7010 | case tk_ID: |
||
7011 | |||
7012 | case tk_proc: |
||
7013 | |||
7014 | case tk_undefproc: |
||
7015 | |||
7016 | if(itok.flag&f_retproc)rettype=(itok.flag&f_retproc)/256+tk_overflowflag-1; |
||
7017 | |||
7018 | op(0x88); |
||
7019 | |||
7020 | nexttok(); |
||
7021 | |||
7022 | if(*ofsstr){ |
||
7023 | |||
7024 | *ofsstr=NULL; |
||
7025 | |||
7026 | break; |
||
7027 | |||
7028 | } |
||
7029 | |||
7030 | calcnumber=FALSE; |
||
7031 | |||
7032 | if(negflag){ |
||
7033 | |||
7034 | op(0x80); |
||
7035 | |||
7036 | op(0xff); |
||
7037 | |||
7038 | op(0xC0+beg); |
||
7039 | |||
7040 | else{ |
||
7041 | |||
7042 | op(0xD8+beg); // NEG beg |
||
7043 | |||
7044 | ClearReg(beg%4); |
||
7045 | |||
7046 | return rettype; |
||
7047 | |||
7048 | |||
7049 | |||
7050 | { |
||
7051 | |||
7052 | if(outtok->sib==CODE16){ |
||
7053 | |||
7054 | if(outtok->post==UNDEF_OFSET){ |
||
7055 | |||
7056 | outtok->post=0; |
||
7057 | |||
7058 | outword(outtok->number); |
||
7059 | |||
7060 | else{ |
||
7061 | |||
7062 | if(rm==rm_mod11)internalerror(badadr); |
||
7063 | |||
7064 | if(outtok->post==UNDEF_OFSET){ |
||
7065 | |||
7066 | outtok->post=0; |
||
7067 | |||
7068 | outword(outtok->number); |
||
7069 | |||
7070 | else if(rm!=rm_mod00)op(outtok->number); |
||
7071 | |||
7072 | } |
||
7073 | |||
7074 | if(rm==rm_d32){ |
||
7075 | |||
7076 | AddUndefOff(2,outtok->name); |
||
7077 | |||
7078 | } |
||
7079 | |||
7080 | } |
||
7081 | |||
7082 | if((rm&7)==rm_sib){ |
||
7083 | |||
7084 | if(rm==4&&(outtok->sib&7)==5){ |
||
7085 | |||
7086 | AddUndefOff(2,outtok->name); |
||
7087 | |||
7088 | } |
||
7089 | |||
7090 | } |
||
7091 | |||
7092 | rm&=rm_mod11; |
||
7093 | |||
7094 | else if(rm==rm_mod10){ |
||
7095 | |||
7096 | AddUndefOff(2,outtok->name); |
||
7097 | |||
7098 | } |
||
7099 | |||
7100 | } |
||
7101 | |||
7102 | } |
||
7103 | |||
7104 | } |
||
7105 | |||
7106 | /*-----------------05.01.00 23:37------------------- |
||
7107 | |||
7108 | операции с переменными типа float |
||
7109 | |||
7110 | int dofloatvar(int addop,int retrez,int terminater) |
||
7111 | |||
7112 | unsigned char next=1, getfromEAX=0; |
||
7113 | |||
7114 | char *wbuf,*rbuf; |
||
7115 | |||
7116 | SINFO wstr; |
||
7117 | |||
7118 | int razr,i=0; |
||
7119 | |||
7120 | if(addop){ |
||
7121 | |||
7122 | razr=8; |
||
7123 | |||
7124 | } |
||
7125 | |||
7126 | strinf.bufstr=NULL; |
||
7127 | |||
7128 | wbuf=bufrm; |
||
7129 | |||
7130 | KillVar(itok.name); |
||
7131 | |||
7132 | nexttok(); |
||
7133 | |||
7134 | case tk_assign: //= |
||
7135 | |||
7136 | convert_type((int *)&sign,(int *)&rettype,&pointr); |
||
7137 | |||
7138 | MultiAssignFloat(type); |
||
7139 | |||
7140 | goto getfromeax; |
||
7141 | |||
7142 | CheckMinusNum(); |
||
7143 | |||
7144 | if(tok==tk_number){ //проверка и суммирование чисел |
||
7145 | |||
7146 | next=0; |
||
7147 | |||
7148 | itok.rm=rettype; |
||
7149 | |||
7150 | } |
||
7151 | |||
7152 | getfromEAX=1; |
||
7153 | |||
7154 | else if(rettype==tk_int||rettype==tk_word)do_e_axmath(sign,r16,&ofsstr); |
||
7155 | |||
7156 | else goto labl1; |
||
7157 | |||
7158 | else{ |
||
7159 | |||
7160 | case tk_number: |
||
7161 | |||
7162 | if(rettype==tk_float){ |
||
7163 | |||
7164 | else if(itok.rm!=tk_float){ |
||
7165 | |||
7166 | *(float *)&itok.number=temp; |
||
7167 | |||
7168 | } |
||
7169 | |||
7170 | if(itok.rm==tk_float)itok.dnumber=itok.fnumber; |
||
7171 | |||
7172 | } |
||
7173 | |||
7174 | for(i=0;i<2;i++){ |
||
7175 | |||
7176 | if((itok.flag&f_reloc)==0&&itok.number==0){ |
||
7177 | |||
7178 | op(0x83); |
||
7179 | |||
7180 | outaddress(&wtok); |
||
7181 | |||
7182 | } |
||
7183 | |||
7184 | op(0x6A); |
||
7185 | |||
7186 | op66(r32); |
||
7187 | |||
7188 | |||
7189 | |||
7190 | outaddress(&wtok); |
||
7191 | |||
7192 | else{ |
||
7193 | |||
7194 | op(0xC7); //mov word[],number |
||
7195 | |||
7196 | outaddress(&wtok); |
||
7197 | |||
7198 | outdword(itok.number); |
||
7199 | |||
7200 | if(i==1||rettype==tk_float)break; |
||
7201 | |||
7202 | wtok.number+=4; |
||
7203 | |||
7204 | } |
||
7205 | |||
7206 | case tk_doublevar: |
||
7207 | |||
7208 | if(tok!=type)goto labl1; |
||
7209 | |||
7210 | char *w1buf; |
||
7211 | |||
7212 | bufrm=NULL; |
||
7213 | |||
7214 | SINFO w1str; |
||
7215 | |||
7216 | strinf.bufstr=NULL; |
||
7217 | |||
7218 | if(tok==tk_doublevar){ |
||
7219 | |||
7220 | op66(r32); |
||
7221 | |||
7222 | op(0xA3); // MOV [dword],EAX |
||
7223 | |||
7224 | else outword(wtok.number); |
||
7225 | |||
7226 | else{ |
||
7227 | |||
7228 | op66(r32); |
||
7229 | |||
7230 | |||
7231 | |||
7232 | } |
||
7233 | |||
7234 | compressoffset(&itok); |
||
7235 | |||
7236 | compressoffset(&wtok); |
||
7237 | |||
7238 | char *w1buf; |
||
7239 | |||
7240 | bufrm=NULL; |
||
7241 | |||
7242 | SINFO w1str; |
||
7243 | |||
7244 | strinf.bufstr=NULL; |
||
7245 | |||
7246 | } |
||
7247 | |||
7248 | break; |
||
7249 | |||
7250 | labl1: |
||
7251 | |||
7252 | getfromEAX=0; |
||
7253 | |||
7254 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7255 | |||
7256 | op(0xd9+addop); |
||
7257 | |||
7258 | outaddress(&wtok); |
||
7259 | |||
7260 | } |
||
7261 | |||
7262 | } |
||
7263 | |||
7264 | next=0; |
||
7265 | |||
7266 | } |
||
7267 | |||
7268 | getfromeax: |
||
7269 | |||
7270 | convert_returnvalue(posiblret,rettype); |
||
7271 | |||
7272 | op66(r32); |
||
7273 | |||
7274 | op(0xA3); // MOV [dword],EAX |
||
7275 | |||
7276 | else outword(wtok.number); |
||
7277 | |||
7278 | else{ |
||
7279 | |||
7280 | op66(r32); |
||
7281 | |||
7282 | op(0x89); op(wtok.rm); // MOV [rmdword],EAX |
||
7283 | |||
7284 | } |
||
7285 | |||
7286 | break; |
||
7287 | |||
7288 | vop=0x28; |
||
7289 | |||
7290 | incvar: |
||
7291 | |||
7292 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7293 | |||
7294 | op(0xd8+addop); |
||
7295 | |||
7296 | outaddress(&wtok); |
||
7297 | |||
7298 | outseg(&wtok,2); //fstp var |
||
7299 | |||
7300 | op(wtok.rm+0x18); |
||
7301 | |||
7302 | fwait3(); |
||
7303 | |||
7304 | break; |
||
7305 | |||
7306 | case tk_minusequals: vop+=0x20; |
||
7307 | |||
7308 | case tk_plusequals: |
||
7309 | |||
7310 | if(itok2.type==tp_stopper){ |
||
7311 | |||
7312 | if((itok.rm==tk_float&&itok.fnumber==1.0)|| |
||
7313 | |||
7314 | (itok.rm!=tk_float&&itok.rm!=tk_double&&itok.lnumber==1)){ |
||
7315 | |||
7316 | break; |
||
7317 | |||
7318 | if((itok.rm==tk_float&&itok.fnumber==0.0)|| |
||
7319 | |||
7320 | switch(vop){ |
||
7321 | |||
7322 | DevideZero(); |
||
7323 | |||
7324 | case 8: |
||
7325 | |||
7326 | if(retrez==tk_floatvar||retrez==tk_doublevar){ |
||
7327 | |||
7328 | outseg(&wtok,2); //fstp var |
||
7329 | |||
7330 | op(wtok.rm+0x18); |
||
7331 | |||
7332 | fwait3(); |
||
7333 | |||
7334 | break; |
||
7335 | |||
7336 | break; |
||
7337 | |||
7338 | } |
||
7339 | |||
7340 | if(itok2.type==tp_opperand){ |
||
7341 | |||
7342 | endequals: |
||
7343 | |||
7344 | endequals1: |
||
7345 | |||
7346 | outseg(&wtok,2); //fsubr var |
||
7347 | |||
7348 | op(wtok.rm+vop); |
||
7349 | |||
7350 | if(retrez==tk_floatvar||retrez==tk_doublevar){ |
||
7351 | |||
7352 | op(0xd9+addop); |
||
7353 | |||
7354 | outaddress(&wtok); |
||
7355 | |||
7356 | } |
||
7357 | |||
7358 | else{ |
||
7359 | |||
7360 | case tk_number: |
||
7361 | |||
7362 | if(itok.rm==tk_double)itok.fnumber=itok.dnumber; |
||
7363 | |||
7364 | float temp=itok.number; |
||
7365 | |||
7366 | } |
||
7367 | |||
7368 | else{ |
||
7369 | |||
7370 | else if(itok.rm!=tk_double)itok.dnumber=itok.lnumber; |
||
7371 | |||
7372 | |||
7373 | |||
7374 | vop=8; //mult |
||
7375 | |||
7376 | else itok.dnumber=1/itok.dnumber; |
||
7377 | |||
7378 | |||
7379 | |||
7380 | op(0xD9+addop); |
||
7381 | |||
7382 | AddFloatConst(itok.lnumber,rettype); |
||
7383 | |||
7384 | if(am32)outword(0); |
||
7385 | |||
7386 | outseg(&wtok,2); //fsubr var |
||
7387 | |||
7388 | op(wtok.rm+vop); |
||
7389 | |||
7390 | if(retrez==tk_floatvar||retrez==tk_doublevar){ |
||
7391 | |||
7392 | op(0xd9+addop); |
||
7393 | |||
7394 | outaddress(&wtok); |
||
7395 | |||
7396 | } |
||
7397 | |||
7398 | case tk_longvar: |
||
7399 | |||
7400 | case tk_floatvar: |
||
7401 | |||
7402 | outseg(&itok,2); //fld val or fild val |
||
7403 | |||
7404 | op(itok.rm); |
||
7405 | |||
7406 | goto endequals1; |
||
7407 | |||
7408 | sign=2; |
||
7409 | |||
7410 | case tk_doublevar: |
||
7411 | |||
7412 | outseg(&itok,2); //fldq val or fild val |
||
7413 | |||
7414 | op(itok.rm+i); |
||
7415 | |||
7416 | goto endequals1; |
||
7417 | |||
7418 | CheckInitBP(); |
||
7419 | |||
7420 | outword(0x6a); |
||
7421 | |||
7422 | addESP+=4; |
||
7423 | |||
7424 | op66(r32); //push var |
||
7425 | |||
7426 | op(0xFF); |
||
7427 | |||
7428 | outaddress(&itok); |
||
7429 | |||
7430 | addESP+=4; |
||
7431 | |||
7432 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7433 | |||
7434 | op(0xd8+addop); |
||
7435 | |||
7436 | outaddress(&wtok); |
||
7437 | |||
7438 | outword(0xC483); |
||
7439 | |||
7440 | } |
||
7441 | |||
7442 | op(0x58); // pop EAX |
||
7443 | |||
7444 | } |
||
7445 | |||
7446 | if(retrez==tk_floatvar||retrez==tk_doublevar){ |
||
7447 | |||
7448 | op(0xd9+addop); |
||
7449 | |||
7450 | outaddress(&wtok); |
||
7451 | |||
7452 | } |
||
7453 | |||
7454 | break; |
||
7455 | |||
7456 | CheckInitBP(); |
||
7457 | |||
7458 | outword(0x6a); |
||
7459 | |||
7460 | op(0x50+(unsigned int)itok.number); |
||
7461 | |||
7462 | addESP+=8; |
||
7463 | |||
7464 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7465 | |||
7466 | op(0xd8+addop); |
||
7467 | |||
7468 | outaddress(&wtok); |
||
7469 | |||
7470 | outword(0xC483); |
||
7471 | |||
7472 | } |
||
7473 | |||
7474 | op(0x58); // pop EAX |
||
7475 | |||
7476 | } |
||
7477 | |||
7478 | if(retrez==tk_floatvar||retrez==tk_doublevar){ |
||
7479 | |||
7480 | op(0xd9+addop); |
||
7481 | |||
7482 | outaddress(&wtok); |
||
7483 | |||
7484 | } |
||
7485 | |||
7486 | break; |
||
7487 | |||
7488 | if(doeaxfloatmath(tk_fpust)==tk_assign){ |
||
7489 | |||
7490 | op66(r32); //push EAX |
||
7491 | |||
7492 | op(0xD9+addop); |
||
7493 | |||
7494 | fwait3(); |
||
7495 | |||
7496 | op66(r32); |
||
7497 | |||
7498 | } |
||
7499 | |||
7500 | } |
||
7501 | |||
7502 | break; |
||
7503 | |||
7504 | int regdi; |
||
7505 | |||
7506 | getoperand(); |
||
7507 | |||
7508 | bufrm=NULL; |
||
7509 | |||
7510 | switch(tok){ |
||
7511 | |||
7512 | CheckInitBP(); |
||
7513 | |||
7514 | outword(0x6a); |
||
7515 | |||
7516 | op(0x50+(unsigned int)itok.number); |
||
7517 | |||
7518 | addESP+=8; |
||
7519 | |||
7520 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7521 | |||
7522 | op(0xd9+addop); |
||
7523 | |||
7524 | outaddress(&wtok); |
||
7525 | |||
7526 | if(am32){ |
||
7527 | |||
7528 | else{ |
||
7529 | |||
7530 | op(4); |
||
7531 | |||
7532 | } |
||
7533 | |||
7534 | int dob; |
||
7535 | |||
7536 | if(!optimizespeed)dob=4; |
||
7537 | |||
7538 | op(0x9E); |
||
7539 | |||
7540 | } |
||
7541 | |||
7542 | op(0x5E); |
||
7543 | |||
7544 | } |
||
7545 | |||
7546 | outseg(&wtok,2);//fstp val |
||
7547 | |||
7548 | op(wtok.rm+0x18); |
||
7549 | |||
7550 | fwait3(); |
||
7551 | |||
7552 | op(0x58+(unsigned int)itok.number); |
||
7553 | |||
7554 | op66(r32); // pop reg32 |
||
7555 | |||
7556 | } |
||
7557 | |||
7558 | outword(0xC483); |
||
7559 | |||
7560 | } |
||
7561 | |||
7562 | RestoreBP(); |
||
7563 | |||
7564 | case tk_longvar: |
||
7565 | |||
7566 | outseg(&itok,2); //fild |
||
7567 | |||
7568 | op(itok.rm); |
||
7569 | |||
7570 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7571 | |||
7572 | op(0xd9+addop); |
||
7573 | |||
7574 | outaddress(&wtok); |
||
7575 | |||
7576 | op(0xDB); |
||
7577 | |||
7578 | outaddress(&itok); |
||
7579 | |||
7580 | op(0xd9+addop); |
||
7581 | |||
7582 | outaddress(&wtok); |
||
7583 | |||
7584 | break; |
||
7585 | |||
7586 | CheckAllMassiv(rbuf,8,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
7587 | |||
7588 | op(0xdd); |
||
7589 | |||
7590 | outaddress(&itok); |
||
7591 | |||
7592 | outseg(&wtok,2); //fld val |
||
7593 | |||
7594 | op(wtok.rm); |
||
7595 | |||
7596 | outseg(&itok,2); //fistp val |
||
7597 | |||
7598 | op(itok.rm+0x38); |
||
7599 | |||
7600 | outseg(&wtok,2); //fstp val |
||
7601 | |||
7602 | op(wtok.rm+0x18); |
||
7603 | |||
7604 | fwait3(); |
||
7605 | |||
7606 | case tk_dwordvar: |
||
7607 | |||
7608 | op66(r32); //push 0L |
||
7609 | |||
7610 | if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; |
||
7611 | |||
7612 | CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
7613 | |||
7614 | outseg(&itok,2); |
||
7615 | |||
7616 | op(itok.rm+0x30); |
||
7617 | |||
7618 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4; |
||
7619 | |||
7620 | fildq_stack(); |
||
7621 | |||
7622 | outseg(&wtok,2); //fld val |
||
7623 | |||
7624 | op(wtok.rm); |
||
7625 | |||
7626 | if(optimizespeed||am32==FALSE){ |
||
7627 | |||
7628 | op(8); |
||
7629 | |||
7630 | else{ |
||
7631 | |||
7632 | op(0x58); // pop EAX |
||
7633 | |||
7634 | addESP-=8; |
||
7635 | |||
7636 | op(0xDB); |
||
7637 | |||
7638 | outaddress(&itok); |
||
7639 | |||
7640 | op(0xd9+addop); |
||
7641 | |||
7642 | outaddress(&wtok); |
||
7643 | |||
7644 | RestoreBP(); |
||
7645 | |||
7646 | case tk_floatvar: |
||
7647 | |||
7648 | CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
7649 | |||
7650 | op(0xd9); |
||
7651 | |||
7652 | outaddress(&itok); |
||
7653 | |||
7654 | outseg(&wtok,2); //fstp val |
||
7655 | |||
7656 | op(wtok.rm); |
||
7657 | |||
7658 | outseg(&itok,2); //fstp val |
||
7659 | |||
7660 | op(itok.rm+0x18); |
||
7661 | |||
7662 | outseg(&wtok,2); //fstp val |
||
7663 | |||
7664 | op(wtok.rm+0x18); |
||
7665 | |||
7666 | fwait3(); |
||
7667 | |||
7668 | else{ |
||
7669 | |||
7670 | CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
7671 | |||
7672 | outseg(&itok,2);// XCHG EAX,[dword] |
||
7673 | |||
7674 | outaddress(&itok); |
||
7675 | |||
7676 | } |
||
7677 | |||
7678 | case tk_doublevar: |
||
7679 | |||
7680 | CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
7681 | |||
7682 | op(0xdd); |
||
7683 | |||
7684 | outaddress(&itok); |
||
7685 | |||
7686 | outseg(&wtok,2); //fld val |
||
7687 | |||
7688 | op(wtok.rm); |
||
7689 | |||
7690 | outseg(&itok,2); //fstp val |
||
7691 | |||
7692 | op(itok.rm+0x18); |
||
7693 | |||
7694 | outseg(&wtok,2); //fstp val |
||
7695 | |||
7696 | op(wtok.rm+0x18); |
||
7697 | |||
7698 | fwait3(); |
||
7699 | |||
7700 | else{ |
||
7701 | |||
7702 | CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); |
||
7703 | |||
7704 | outseg(&itok,2);// XCHG EAX,[dword] |
||
7705 | |||
7706 | outaddress(&itok); |
||
7707 | |||
7708 | } |
||
7709 | |||
7710 | case tk_fpust: |
||
7711 | |||
7712 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
7713 | |||
7714 | op(0xd9+addop); |
||
7715 | |||
7716 | outaddress(&wtok); |
||
7717 | |||
7718 | op(0xC8+itok.number+1); |
||
7719 | |||
7720 | op(0xd9+addop); |
||
7721 | |||
7722 | outaddress(&wtok); |
||
7723 | |||
7724 | default: swaperror(); break; |
||
7725 | |||
7726 | break; |
||
7727 | |||
7728 | } |
||
7729 | |||
7730 | if(terminater==tk_semicolon)seminext(); |
||
7731 | |||
7732 | return retrez; |
||
7733 | |||
7734 | |||
7735 | |||
7736 | { |
||
7737 | |||
7738 | if(am32)outword(0x242c); //fildq ssdword[bp-8]/ssdword[esp] |
||
7739 | |||
7740 | if(short_ok(size,FALSE)==0){ |
||
7741 | |||
7742 | outword(-size); |
||
7743 | |||
7744 | else{ |
||
7745 | |||
7746 | op(-size); |
||
7747 | |||
7748 | } |
||
7749 | |||
7750 | |||
7751 | |||
7752 | { |
||
7753 | |||
7754 | } |
||
7755 | |||
7756 | void fistp2_stack(int size) |
||
7757 | |||
7758 | if(am32)outword(0x241c); //fistp ssdword[ebp+2]/ssdword[esp] |
||
7759 | |||
7760 | if(short_ok(size,FALSE)==0){ |
||
7761 | |||
7762 | outword(-size); |
||
7763 | |||
7764 | else{ |
||
7765 | |||
7766 | op(-size); |
||
7767 | |||
7768 | } |
||
7769 | |||
7770 | |||
7771 | |||
7772 | { |
||
7773 | |||
7774 | fistp2_stack(localsize+4+addop); |
||
7775 | |||
7776 | |||
7777 | |||
7778 | { |
||
7779 | |||
7780 | else{ |
||
7781 | |||
7782 | op(0x86); |
||
7783 | |||
7784 | } |
||
7785 | |||
7786 | op(0x46); |
||
7787 | |||
7788 | } |
||
7789 | |||
7790 | } |
||
7791 | |||
7792 | void FloatToNumer(int addop) |
||
7793 | |||
7794 | { |
||
7795 | |||
7796 | op(0xD9+addop); |
||
7797 | |||
7798 | fistp_stack(); |
||
7799 | |||
7800 | fwait3(); |
||
7801 | |||
7802 | op(0x58); //pop reg |
||
7803 | |||
7804 | } |
||
7805 | |||
7806 | void Float2reg32(int reg,int addop,int reg1,int reg2) |
||
7807 | |||
7808 | CheckInitBP(); |
||
7809 | |||
7810 | op(0x50); //push AX |
||
7811 | |||
7812 | addESP+=4; |
||
7813 | |||
7814 | outseg(&itok,2); //fld floatvar |
||
7815 | |||
7816 | op(itok.rm); |
||
7817 | |||
7818 | fistp_stack(); |
||
7819 | |||
7820 | op66(r32); |
||
7821 | |||
7822 | addESP-=4; |
||
7823 | |||
7824 | RestoreBP(); |
||
7825 | |||
7826 | |||
7827 | |||
7828 | { |
||
7829 | |||
7830 | CheckAllMassiv(bufrm,1,&strinf); |
||
7831 | |||
7832 | if(tok==tk_bytevar&&optimizespeed&&chip>3&&chip<7){ |
||
7833 | |||
7834 | outseg(&itok,2); |
||
7835 | |||
7836 | } |
||
7837 | |||
7838 | outseg(&itok,3); |
||
7839 | |||
7840 | if(tok==tk_bytevar)op(0xb6); |
||
7841 | |||
7842 | } |
||
7843 | |||
7844 | outaddress(&itok); |
||
7845 | |||
7846 | outword(0xDF50); //push ax |
||
7847 | |||
7848 | addESP+=2; |
||
7849 | |||
7850 | } |
||
7851 | |||
7852 | void reginstack(int *numstak,int *nums) |
||
7853 | |||
7854 | CheckInitBP(); |
||
7855 | |||
7856 | if(tok==tk_beg){ |
||
7857 | |||
7858 | xorAXAX(); |
||
7859 | |||
7860 | op(0xC0+itok.number*8); //mov al,beg |
||
7861 | |||
7862 | else if(itok.number==AL)xorAHAH(); |
||
7863 | |||
7864 | outword(0xB60F); /* MOVZX AX,beg */ |
||
7865 | |||
7866 | } |
||
7867 | |||
7868 | } |
||
7869 | |||
7870 | op66(tok==tk_reg32?r32:r16); |
||
7871 | |||
7872 | if(tok==tk_reg){ |
||
7873 | |||
7874 | *numstak+=4; |
||
7875 | |||
7876 | fld_stack(*nums+*numstak); |
||
7877 | |||
7878 | else if(tok==tk_beg){ |
||
7879 | |||
7880 | *numstak+=2; |
||
7881 | |||
7882 | fld_stack(*nums+*numstak); |
||
7883 | |||
7884 | else{ |
||
7885 | |||
7886 | addESP+=8; |
||
7887 | |||
7888 | } |
||
7889 | |||
7890 | |||
7891 | |||
7892 | { |
||
7893 | |||
7894 | op66(tok==tk_wordvar?r16:r32); |
||
7895 | |||
7896 | if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; |
||
7897 | |||
7898 | op66(tok==tk_wordvar?r16:r32); |
||
7899 | |||
7900 | op(0xFF); |
||
7901 | |||
7902 | outaddress(&itok); |
||
7903 | |||
7904 | op(0xDB); |
||
7905 | |||
7906 | *numstak+=4; |
||
7907 | |||
7908 | } |
||
7909 | |||
7910 | addESP+=8; |
||
7911 | |||
7912 | fildq2_stack(*nums+*numstak); |
||
7913 | |||
7914 | } |
||
7915 | |||
7916 | void intinstack(int addop) |
||
7917 | |||
7918 | CheckAllMassiv(bufrm,tok==tk_intvar?2:4+addop,&strinf); |
||
7919 | |||
7920 | if(tok==tk_intvar||tok==tk_qwordvar)op(0xDF); |
||
7921 | |||
7922 | else op(0xDB); |
||
7923 | |||
7924 | outaddress(&itok); |
||
7925 | |||
7926 | |||
7927 | |||
7928 | { |
||
7929 | |||
7930 | static int nums=0; |
||
7931 | |||
7932 | long long lnumber; |
||
7933 | |||
7934 | ols=localsize; |
||
7935 | |||
7936 | next=1; |
||
7937 | |||
7938 | if(CheckMinusNum()==FALSE){ |
||
7939 | |||
7940 | getoperand(am32==TRUE?EAX:BX); |
||
7941 | |||
7942 | } |
||
7943 | |||
7944 | // printf("rm=%d %e %e %08X\n",itok.rm,itok.fnumber,itok.dnumber,itok.number); |
||
7945 | |||
7946 | itok.number=doconstfloatmath(); |
||
7947 | |||
7948 | } |
||
7949 | |||
7950 | itok.lnumber=doconstdoublemath(); |
||
7951 | |||
7952 | } |
||
7953 | |||
7954 | if(itok.type==tp_stopper){ |
||
7955 | |||
7956 | // if(itok.rm==tk_double&&addop==0)itok.fnumber=itok.dnumber; |
||
7957 | |||
7958 | if(itok.rm==tk_double){ |
||
7959 | |||
7960 | itok.lnumber=lnumber>>32; |
||
7961 | |||
7962 | for(i=0;i<2;i++){ |
||
7963 | |||
7964 | if(short_ok(itok.number,TRUE)){ //PUSH number |
||
7965 | |||
7966 | op(itok.number); |
||
7967 | |||
7968 | else{ |
||
7969 | |||
7970 | outdword(itok.number); |
||
7971 | |||
7972 | if(itok.rm!=tk_double)break; |
||
7973 | |||
7974 | itok.number=lnumber; |
||
7975 | |||
7976 | return itreturn; |
||
7977 | |||
7978 | if(itreturn==tk_reg32){ |
||
7979 | |||
7980 | return itreturn; |
||
7981 | |||
7982 | if(itreturn==tk_reg64){ |
||
7983 | |||
7984 | MovRegNum(r32,0,itok.lnumber>>=32,reg/256); |
||
7985 | |||
7986 | } |
||
7987 | |||
7988 | } |
||
7989 | |||
7990 | op66(r32); |
||
7991 | |||
7992 | if(addop){ |
||
7993 | |||
7994 | op(0x50); //push eax |
||
7995 | |||
7996 | op(0x55); //push bp |
||
7997 | |||
7998 | if(initBP>1)initBP++; |
||
7999 | |||
8000 | } |
||
8001 | |||
8002 | switch(tok){ |
||
8003 | |||
8004 | casenumber: |
||
8005 | |||
8006 | if((itok.rm==tk_float&&itok.fnumber==1.0)|| |
||
8007 | |||
8008 | (itok.rm!=tk_float&&itok.rm!=tk_double&&itok.lnumber==1)){ |
||
8009 | |||
8010 | break; |
||
8011 | |||
8012 | if((itok.rm==tk_float&&itok.fnumber==0.0)|| |
||
8013 | |||
8014 | outword(0xEED9); //FLDZ |
||
8015 | |||
8016 | } |
||
8017 | |||
8018 | op((am32==FALSE?0x06:0x05)); //fld |
||
8019 | |||
8020 | outword(0); |
||
8021 | |||
8022 | break; |
||
8023 | |||
8024 | getoperand(am32==TRUE?EAX:BX); |
||
8025 | |||
8026 | break; |
||
8027 | |||
8028 | case tk_id: |
||
8029 | |||
8030 | case tk_apiproc: |
||
8031 | |||
8032 | case tk_undefproc: |
||
8033 | |||
8034 | onums=nums; |
||
8035 | |||
8036 | vop=procdo(tk_fpust); //возвр из процедур |
||
8037 | |||
8038 | if(tok2==tk_semicolon&&vop!=tk_fpust&&vop!=tk_double){ |
||
8039 | |||
8040 | return tk_assign; |
||
8041 | |||
8042 | break; |
||
8043 | |||
8044 | case tk_doublevar: |
||
8045 | |||
8046 | case tk_floatvar: |
||
8047 | |||
8048 | case tk_intvar: |
||
8049 | |||
8050 | break; |
||
8051 | |||
8052 | case tk_wordvar: |
||
8053 | |||
8054 | break; |
||
8055 | |||
8056 | case tk_bytevar: |
||
8057 | |||
8058 | break; |
||
8059 | |||
8060 | case tk_reg32: |
||
8061 | |||
8062 | reginstack(&numstak,&nums); |
||
8063 | |||
8064 | case tk_fpust: |
||
8065 | |||
8066 | op(0xD9); |
||
8067 | |||
8068 | } |
||
8069 | |||
8070 | default: valueexpected(); break; |
||
8071 | |||
8072 | if(negflag){ |
||
8073 | |||
8074 | negflag=0; |
||
8075 | |||
8076 | if(next==1)nexttok(); |
||
8077 | |||
8078 | next=1; |
||
8079 | |||
8080 | i=0; |
||
8081 | |||
8082 | case tk_multminus: negflag=1; goto mult; |
||
8083 | |||
8084 | case tk_div: vop+=0x10; |
||
8085 | |||
8086 | mult: |
||
8087 | |||
8088 | case tk_plus: |
||
8089 | |||
8090 | switch(tok){ |
||
8091 | |||
8092 | |||
8093 | |||
8094 | itok.rm=tk_double; |
||
8095 | |||
8096 | if((itok.rm==tk_float&&itok.fnumber==1.0)|| |
||
8097 | |||
8098 | num1: |
||
8099 | |||
8100 | outword(0xE8D9); //FLD1 |
||
8101 | |||
8102 | op(0xC1+vop); |
||
8103 | |||
8104 | break; |
||
8105 | |||
8106 | op(0xd8+(itok.rm==tk_float?0:4)); |
||
8107 | |||
8108 | if(vop==0x38){ // div 22.12.05 22:10 |
||
8109 | |||
8110 | if(itok.rm==tk_float)itok.fnumber=1/itok.fnumber; |
||
8111 | |||
8112 | } |
||
8113 | |||
8114 | |||
8115 | |||
8116 | AddFloatConst(itok.lnumber,itok.rm); |
||
8117 | |||
8118 | if(am32)outword(0); |
||
8119 | |||
8120 | case tk_doublevar: |
||
8121 | |||
8122 | case tk_floatvar: |
||
8123 | |||
8124 | CheckAllMassiv(bufrm,4+i,&strinf); |
||
8125 | |||
8126 | op(0xd8+i); |
||
8127 | |||
8128 | outaddress(&itok); |
||
8129 | |||
8130 | case tk_longvar: |
||
8131 | |||
8132 | CheckAllMassiv(bufrm,4,&strinf); |
||
8133 | |||
8134 | op(tok==tk_intvar?0xDE:0xDA); |
||
8135 | |||
8136 | op(itok.rm+vop); |
||
8137 | |||
8138 | break; |
||
8139 | |||
8140 | intinstack(4); |
||
8141 | |||
8142 | op(0xC1+vop);//fsubpr st1 |
||
8143 | |||
8144 | case tk_dwordvar: |
||
8145 | |||
8146 | wordinstack(&numstak,&nums); |
||
8147 | |||
8148 | op(0xC1+vop);//fsubpr st1 |
||
8149 | |||
8150 | case tk_beg: |
||
8151 | |||
8152 | case tk_reg: |
||
8153 | |||
8154 | op(0xde); |
||
8155 | |||
8156 | break; |
||
8157 | |||
8158 | case tk_bytevar: |
||
8159 | |||
8160 | op(0xde); |
||
8161 | |||
8162 | break; |
||
8163 | |||
8164 | if(vop==0x38||vop==0x28)vop-=8; |
||
8165 | |||
8166 | op(0xC0+vop+itok.number);//fsubpr st |
||
8167 | |||
8168 | default: valueexpected(); break; |
||
8169 | |||
8170 | break; |
||
8171 | |||
8172 | } |
||
8173 | |||
8174 | outword(0xe0d9); //fchs |
||
8175 | |||
8176 | } |
||
8177 | |||
8178 | } |
||
8179 | |||
8180 | if(itreturn==tk_stackstart){ |
||
8181 | |||
8182 | op(0xD9+addop); |
||
8183 | |||
8184 | numstak-=2; |
||
8185 | |||
8186 | else{ |
||
8187 | |||
8188 | op66(r32); |
||
8189 | |||
8190 | addESP+=4; |
||
8191 | |||
8192 | else numstak-=4; |
||
8193 | |||
8194 | if(numstak<4){ |
||
8195 | |||
8196 | op(0x50); //push eax |
||
8197 | |||
8198 | } |
||
8199 | |||
8200 | } |
||
8201 | |||
8202 | if(numstak==0)outword(0x241C); //fstp ssdword[esp] |
||
8203 | |||
8204 | outword(0x245C); //fstp ssdword[esp+numstak] |
||
8205 | |||
8206 | } |
||
8207 | |||
8208 | fwait3(); |
||
8209 | |||
8210 | else if(itreturn==tk_reg32||itreturn==tk_reg64){ |
||
8211 | |||
8212 | if(itreturn==tk_reg64)i=8; |
||
8213 | |||
8214 | op66(r32); |
||
8215 | |||
8216 | if(itreturn==tk_reg64){ |
||
8217 | |||
8218 | op(0x50); //push eax |
||
8219 | |||
8220 | numstak+=i; |
||
8221 | |||
8222 | } |
||
8223 | |||
8224 | // op(itreturn==tk_reg32?0xD9:0xDB); |
||
8225 | |||
8226 | fwait3(); |
||
8227 | |||
8228 | op66(r32); |
||
8229 | |||
8230 | op66(r32); |
||
8231 | |||
8232 | } |
||
8233 | |||
8234 | op66(r32); |
||
8235 | |||
8236 | } |
||
8237 | |||
8238 | addESP-=i; |
||
8239 | |||
8240 | if(localsize!=(unsigned int)ols){ |
||
8241 | |||
8242 | Leave(); |
||
8243 | |||
8244 | } |
||
8245 | |||
8246 | if(numstak<128){ |
||
8247 | |||
8248 | op(numstak); |
||
8249 | |||
8250 | else{ |
||
8251 | |||
8252 | outword(numstak); |
||
8253 | |||
8254 | addESP-=numstak; |
||
8255 | |||
8256 | RestoreBP(); |
||
8257 | |||
8258 | return itreturn; |
||
8259 | |||
8260 | |||
8261 | |||
8262 | { |
||
8263 | |||
8264 | if(tok!=tk_fpust)outword(0xf7d9); //fincstp |
||
8265 | |||
8266 | // outword(0xf6d9); //fdecstp |
||
8267 | |||
8268 | if(num){ |
||
8269 | |||
8270 | op(0xC8+num); |
||
8271 | |||
8272 | } |
||
8273 | |||
8274 | void dofloatstack(int num) |
||
8275 | |||
8276 | int vop=0; |
||
8277 | |||
8278 | switch(tok){ |
||
8279 | |||
8280 | getoperand(am32==TRUE?EAX:BX); |
||
8281 | |||
8282 | break; |
||
8283 | |||
8284 | case tk_minusequals: vop+=0x20; |
||
8285 | |||
8286 | case tk_plusequals: |
||
8287 | |||
8288 | float2stack(0); |
||
8289 | |||
8290 | op(0xdc); |
||
8291 | |||
8292 | break; |
||
8293 | |||
8294 | getoperand(am32==TRUE?EAX:BX); |
||
8295 | |||
8296 | case tk_fpust: |
||
8297 | |||
8298 | op(0xC8+num); |
||
8299 | |||
8300 | op(0xC8+itok.number); |
||
8301 | |||
8302 | op(0xC8+num); |
||
8303 | |||
8304 | case tk_doublevar: |
||
8305 | |||
8306 | case tk_floatvar: |
||
8307 | |||
8308 | outseg(&itok,2); //fld val |
||
8309 | |||
8310 | op(itok.rm); |
||
8311 | |||
8312 | op(0xD9); |
||
8313 | |||
8314 | outseg(&itok,2); //fstp val |
||
8315 | |||
7626 | siemargl | 8316 | op(itok.rm+0x18); |
6446 | GerdtR | 8317 | |
7626 | siemargl | 8318 | break; |
6446 | GerdtR | 8319 | |
8320 | swaperror(); |
||
8321 | |||
8322 | } |
||
8323 | |||
8324 | break; |
||
8325 | |||
8326 | |||
8327 | |||
8328 | } |
||
8329 | |||
8330 | void RestoreBP() |
||
8331 | |||
8332 | if(am32==0&&initBP==2){ |
||
8333 | |||
8334 | initBP=0; |
||
8335 | |||
8336 | } |
||
8337 | |||
8338 | void CheckInitBP() |
||
8339 | |||
8340 | if(am32==0&&initBP==0){ |
||
8341 | |||
8342 | outword(0xe589);//mov bp,sp |
||
8343 | |||
8344 | } |
||
8345 | |||
8346 | |||
8347 | |||
8348 | { |
||
8349 | |||
8350 | CheckPosts(); |
||
8351 | |||
8352 | (postbuf+posts)->type=(unsigned short)(am32==FALSE?FIX_VAR:FIX_VAR32); |
||
8353 | |||
8354 | } |
||
8355 | |||
8356 | (postbuf+posts)->type=(unsigned short)(am32==FALSE?FIX_CODE:FIX_CODE32); |
||
8357 | |||
8358 | } |
||
8359 | |||
8360 | } |
||
8361 | |||
8362 | } |
||
8363 | |||
8364 | void fwait3() |
||
8365 | |||
8366 | if(chip<4&&tok2!=tk_floatvar&&tok2!=tk_doublevar&&tok2!=tk_float&&tok2!=tk_double)op(0x9B); |
||
8367 | |||
8368 | |||
8369 | |||
8370 | { |
||
8371 | |||
8372 | unsigned int ofs; |
||
8373 | |||
8374 | if(type==(floatnum+i)->type){ |
||
8375 | |||
8376 | if(type==tk_float){ |
||
8377 | |||
8378 | } |
||
8379 | |||
8380 | } |
||
8381 | |||
8382 | if(numfloatconst==0){ |
||
8383 | |||
8384 | maxnumfloatconst=STEPFLOATCONST; |
||
8385 | |||
8386 | } |
||
8387 | |||
8388 | floatnum=(LISTFLOAT *)REALLOC(floatnum,(maxnumfloatconst+STEPFLOATCONST)*sizeof(LISTFLOAT)); |
||
8389 | |||
8390 | } |
||
8391 | |||
8392 | (floatnum+i)->type=type; |
||
8393 | |||
8394 | if(type==tk_float)(floatnum+i)->num[0]=*(unsigned long *)&fnumber; |
||
8395 | |||
8396 | ofsfloatlist+=(type==tk_float?4:8); |
||
8397 | |||
8398 | CheckPosts(); |
||
8399 | |||
8400 | (postbuf+posts)->loc=outptrdata; |
||
8401 | |||
8402 | posts++; |
||
8403 | |||
8404 | |||
8405 | |||
8406 | { |
||
8407 | |||
8408 | (postbuf+posts)->type=EXT_VAR; |
||
8409 | |||
8410 | (postbuf+posts)->num=*id&0xFFFF; //id номер внешней переменной |
||
8411 | |||
8412 | posts++; |
||
8413 | |||
8414 | |||
8415 | |||
8416 | { |
||
8417 | |||
8418 | if(stok->post==USED_DIN_VAR){ |
||
8419 | |||
8420 | // printf("Add tok=%d %s\n",stok->rec->rectok,stok->rec->recid); |
||
8421 | |||
8422 | if(stok->rec->rectok==tk_structvar&&stok->rec->recsib==tp_gvar){ |
||
8423 | |||
8424 | } |
||
8425 | |||
8426 | } |
||
8427 | |||
8428 | else (postbuf+posts)->type=(unsigned short)(am32==FALSE?POST_VAR:POST_VAR32); |
||
8429 | |||
8430 | posts++; |
||
8431 | |||
8432 | |||
8433 | |||
8434 | { |
||
8435 | |||
8436 | int nreg; |
||
8437 | |||
8438 | if(relocf==0){ |
||
8439 | |||
8440 | ConstToReg(number,reg,razr); |
||
8441 | |||
8442 | else if(num |
||
8443 | |||
8444 | if(num==1){ |
||
8445 | |||
8446 | return; |
||
8447 | |||
8448 | if(num==2){ |
||
8449 | |||
8450 | op66(razr); |
||
8451 | |||
8452 | return; |
||
8453 | |||
8454 | if(razr==r32&&short_ok(num,TRUE)){ |
||
8455 | |||
8456 | op(0xC0+reg); |
||
8457 | |||
8458 | return; |
||
8459 | |||
8460 | |||
8461 | |||
8462 | num=num-number; |
||
8463 | |||
8464 | op(0x48+reg); //dec reg |
||
8465 | |||
8466 | } |
||
8467 | |||
8468 | op(0x48+reg); //dec reg |
||
8469 | |||
8470 | op(0x48+reg); //dec reg |
||
8471 | |||
8472 | } |
||
8473 | |||
8474 | op(0x83); |
||
8475 | |||
8476 | op(num); |
||
8477 | |||
8478 | } |
||
8479 | |||
8480 | } |
||
8481 | |||
8482 | ConstToReg(number,reg,razr); |
||
8483 | |||
8484 | op(0x89); |
||
8485 | |||
8486 | return; |
||
8487 | |||
8488 | else if((number-num)==1){ |
||
8489 | |||
8490 | op(128+64+nreg*8+reg); |
||
8491 | |||
8492 | op(0x40+reg); //inc reg |
||
8493 | |||
8494 | } |
||
8495 | |||
8496 | if((num-number)==1){ |
||
8497 | |||
8498 | op(128+64+nreg*8+reg); |
||
8499 | |||
8500 | op(0x48+reg); //dec reg |
||
8501 | |||
8502 | } |
||
8503 | |||
8504 | } |
||
8505 | |||
8506 | if(number==0){ |
||
8507 | |||
8508 | } // XOR reg,reg |
||
8509 | |||
8510 | op(0x83); //or reg,-1 |
||
8511 | |||
8512 | op(0xFF); |
||
8513 | |||
8514 | else if(number==1&&razr==r32){ |
||
8515 | |||
8516 | op66(razr); |
||
8517 | |||
8518 | } |
||
8519 | |||
8520 | op(0x6A); |
||
8521 | |||
8522 | op66(razr); |
||
8523 | |||
8524 | } |
||
8525 | |||
8526 | } |
||
8527 | |||
8528 | stdmov: |
||
8529 | |||
8530 | if(relocf)AddReloc(); |
||
8531 | |||
8532 | ClearReg(reg); |
||
8533 | |||
8534 | } |
||
8535 | |||
8536 | void NegReg(int razr,int reg) |
||
8537 | |||
8538 | op66(razr); |
||
8539 | |||
8540 | op(0x83); //and reg,-1 |
||
8541 | |||
8542 | op(0xFF); |
||
8543 | |||
8544 | op(0x40+reg); //inc reg |
||
8545 | |||
8546 | else{ |
||
8547 | |||
8548 | op(0xD8+reg); // NEG reg |
||
8549 | |||
8550 | ClearReg(reg); |
||
8551 | |||
8552 | |||
8553 | |||
8554 | { |
||
8555 | |||
8556 | if(tok==tk_number){ |
||
8557 | |||
8558 | op66(razr); |
||
8559 | |||
8560 | } |
||
8561 | |||
8562 | if(chip<2&&razr==r16){ |
||
8563 | |||
8564 | goto rrshift; |
||
8565 | |||
8566 | else{ |
||
8567 | |||
8568 | op(0xc1); |
||
8569 | |||
8570 | op((unsigned int)itok.number); |
||
8571 | |||
8572 | } |
||
8573 | |||
8574 | nexttok(); |
||
8575 | |||
8576 | else if(reg==ECX)return FALSE; |
||
8577 | |||
8578 | nexttok(); |
||
8579 | |||
8580 | } |
||
8581 | |||
8582 | rrshift: |
||
8583 | |||
8584 | warningreg(begs[1]); |
||
8585 | |||
8586 | op66(razr); |
||
8587 | |||
8588 | op(0xE8+reg+sign); // SHL xXX,CL |
||
8589 | |||
8590 | return TRUE; |
||
8591 | |||
8592 | |||
8593 | |||
8594 | { |
||
8595 | |||
8596 | nexttok(); |
||
8597 | |||
8598 | else if(itok.rm==tk_double)itok.lnumber|=0x8000000000000000LL; |
||
8599 | |||
8600 | return TRUE; |
||
8601 | |||
8602 | return FALSE; |
||
8603 | |||
8604 | |||
8605 | |||
8606 | { |
||
8607 | |||
8608 | int ii=0; |
||
8609 | |||
8610 | switch(tok){ |
||
8611 | |||
8612 | RegMulNum(reg,itok.number,razr,0,&i,itok.flag); |
||
8613 | |||
8614 | case tk_postnumber: |
||
8615 | |||
8616 | if(chip<2&&razr==r16)regmathoperror(); |
||
8617 | |||
8618 | op(0x69); |
||
8619 | |||
8620 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
8621 | |||
8622 | razr==r16?outword(itok.number):outdword(itok.number); |
||
8623 | |||
8624 | case tk_apioffset: |
||
8625 | |||
8626 | op66(razr); |
||
8627 | |||
8628 | op(0xc0+reg*9); |
||
8629 | |||
8630 | break; |
||
8631 | |||
8632 | ii=4; |
||
8633 | |||
8634 | if(reg!=EDX)i=EDX; |
||
8635 | |||
8636 | op66(razr); |
||
8637 | |||
8638 | op(0xC0+reg*8+i); // IMUL reg,EDX/EAX |
||
8639 | |||
8640 | break; |
||
8641 | |||
8642 | i=4; |
||
8643 | |||
8644 | case tk_dwordvar: |
||
8645 | |||
8646 | goto mulword; |
||
8647 | |||
8648 | case tk_wordvar: |
||
8649 | |||
8650 | if(razr==r32)goto defmul1; |
||
8651 | |||
8652 | mulword: |
||
8653 | |||
8654 | op66(razr); |
||
8655 | |||
8656 | outword(0xAF0F); |
||
8657 | |||
8658 | outaddress(&itok); |
||
8659 | |||
8660 | case tk_bits: |
||
8661 | |||
8662 | i=itok.bit.siz+itok.bit.ofs; |
||
8663 | |||
8664 | if(i<=32)vops=r32; |
||
8665 | |||
8666 | if(vops |
||
8667 | |||
8668 | if(reg==CX)reg2s=DI; |
||
8669 | |||
8670 | if(vops==r64)vops=r32; |
||
8671 | |||
8672 | itok.number=reg2s; |
||
8673 | |||
8674 | case tk_reg: |
||
8675 | |||
8676 | if(razr==r32){ |
||
8677 | |||
8678 | outword(0xB70F); |
||
8679 | |||
8680 | op(0xC0+reg); |
||
8681 | |||
8682 | } |
||
8683 | |||
8684 | warningreg(regs[razr/2-1][itok.number]); |
||
8685 | |||
8686 | case tk_reg32: |
||
8687 | |||
8688 | op66(razr); |
||
8689 | |||
8690 | op(0xC0+reg*8+(unsigned int)itok.number); |
||
8691 | |||
8692 | case tk_ID: |
||
8693 | |||
8694 | case tk_proc: |
||
8695 | |||
8696 | case tk_undefproc: |
||
8697 | |||
8698 | procdo(razr==r16?tk_word:tk_dword); |
||
8699 | |||
8700 | goto defmul; |
||
8701 | |||
8702 | case tk_charvar: |
||
8703 | |||
8704 | case tk_bytevar: |
||
8705 | |||
8706 | defmul1: |
||
8707 | |||
8708 | if(reg==EDX)i=ECX; |
||
8709 | |||
8710 | defmul: |
||
8711 | |||
8712 | outword(0xAF0F); |
||
8713 | |||
8714 | warningreg(regs[razr/2-1][2]); |
||
8715 | |||
8716 | if(i!=EAX)next=0; |
||
8717 | |||
8718 | default: regmathoperror(); break; |
||
8719 | |||
8720 | return next; |
||
8721 | |||
8722 | |||
8723 | |||
8724 | { |
||
8725 | |||
8726 | char *ofsstr=NULL; |
||
8727 | |||
8728 | i=itok.bit.siz+itok.bit.ofs; |
||
8729 | |||
8730 | if(i<=32)next=r32; |
||
8731 | |||
8732 | bits2reg(CX,(razr |
||
8733 | |||
8734 | if(next==r64)next=r32; |
||
8735 | |||
8736 | warningreg(regs[next/2-1][ECX]); |
||
8737 | |||
8738 | } |
||
8739 | |||
8740 | next=1; |
||
8741 | |||
8742 | if(razr==r16)itok.number&=0xffff; |
||
8743 | |||
8744 | if((itok.flag&f_reloc)!=0)goto defal; |
||
8745 | |||
8746 | if(caselong(itok.number)!=NUMNUM){ |
||
8747 | |||
8748 | if(itok.number==0)ZeroReg(EAX,razr); |
||
8749 | |||
8750 | op66(razr); |
||
8751 | |||
8752 | op(itok.number); |
||
8753 | |||
8754 | else{ |
||
8755 | |||
8756 | op(0x25); // AND EAX,number-1 |
||
8757 | |||
8758 | } |
||
8759 | |||
8760 | } |
||
8761 | |||
8762 | defal: |
||
8763 | |||
8764 | DivNum2(itok.number,razr,sign); |
||
8765 | |||
8766 | } |
||
8767 | |||
8768 | else{ //деление |
||
8769 | |||
8770 | switch(itok.number){ |
||
8771 | |||
8772 | DevideZero(); |
||
8773 | |||
8774 | case 1: break; |
||
8775 | |||
8776 | if(expand==TRUE){ |
||
8777 | |||
8778 | if((chip>2||razr==r32)&&chip!=5&&chip!=6){ |
||
8779 | |||
8780 | setzeroflag=TRUE; |
||
8781 | |||
8782 | else{ |
||
8783 | |||
8784 | op66(razr); |
||
8785 | |||
8786 | setzeroflag=FALSE; |
||
8787 | |||
8788 | ClearReg(AX); |
||
8789 | |||
8790 | break; |
||
8791 | |||
8792 | op66(razr); |
||
8793 | |||
8794 | else outword(0xE8D1); // SHR AX,1 |
||
8795 | |||
8796 | ClearReg(AX); |
||
8797 | |||
8798 | default: |
||
8799 | |||
8800 | if(vop!=NUMNUM){ |
||
8801 | |||
8802 | if(chip>2||razr==r32){ |
||
8803 | |||
8804 | op(0x0f); |
||
8805 | |||
8806 | op(vop); |
||
8807 | |||
8808 | ClearReg(AX); |
||
8809 | |||
8810 | } |
||
8811 | |||
8812 | if(optimizespeed==FALSE)goto divin; |
||
8813 | |||
8814 | if(sign)outword(0xFad1); // SAR AX,1 |
||
8815 | |||
8816 | outdword(0xfae2d8d1); //rcr ax,1 LOOP -6 |
||
8817 | |||
8818 | setzeroflag=FALSE; |
||
8819 | |||
8820 | ConstToReg(vop,CL,r8); |
||
8821 | |||
8822 | } |
||
8823 | |||
8824 | if(chip<2&&razr==r16){ |
||
8825 | |||
8826 | if(sign)outword(0xF8D3); // SAR AX,CL |
||
8827 | |||
8828 | warningreg(begs[1]); |
||
8829 | |||
8830 | ConstToReg(vop,CL,r8); |
||
8831 | |||
8832 | else{ |
||
8833 | |||
8834 | if(sign)outword(0xF8C1); // SAR AX,num |
||
8835 | |||
8836 | op(vop); |
||
8837 | |||
8838 | } |
||
8839 | |||
8840 | } |
||
8841 | |||
8842 | else{ |
||
8843 | |||
8844 | else{ |
||
8845 | |||
8846 | |||
8847 | |||
8848 | DivNum2(itok.number,razr,sign); |
||
8849 | |||
8850 | } |
||
8851 | |||
8852 | } |
||
8853 | |||
8854 | else{ |
||
8855 | |||
8856 | i=4; |
||
8857 | |||
8858 | } |
||
8859 | |||
8860 | Float2reg32(ECX,i); |
||
8861 | |||
8862 | itok.number=ECX; |
||
8863 | |||
8864 | sign=1; |
||
8865 | |||
8866 | switch(tok){ |
||
8867 | |||
8868 | i=4; |
||
8869 | |||
8870 | case tk_dwordvar: |
||
8871 | |||
8872 | case tk_intvar: |
||
8873 | |||
8874 | if(razr==r32&&(tok==tk_intvar||tok==tk_wordvar))goto defdiv; |
||
8875 | |||
8876 | CheckAllMassiv(bufrm,i,&strinf); |
||
8877 | |||
8878 | op66(razr); |
||
8879 | |||
8880 | op(0xF7); |
||
8881 | |||
8882 | else op(0x30+itok.rm); /* DIV word ptr [#] */ |
||
8883 | |||
8884 | ClearReg(AX); |
||
8885 | |||
8886 | case tk_reg: |
||
8887 | |||
8888 | i=itok.number; |
||
8889 | |||
8890 | if(expand==FALSE)ClearDX(razr,sign); |
||
8891 | |||
8892 | op(0xF7); |
||
8893 | |||
8894 | else op(0xF0+i); /* DIV ECX */ |
||
8895 | |||
8896 | warningreg(regs[1][2]); |
||
8897 | |||
8898 | ClearReg(CX); |
||
8899 | |||
8900 | } |
||
8901 | |||
8902 | if(expand==FALSE)ClearDX(razr,sign); |
||
8903 | |||
8904 | op(0xF7); |
||
8905 | |||
8906 | else op(0xF0+(unsigned int)itok.number); |
||
8907 | |||
8908 | break; |
||
8909 | |||
8910 | case tk_id: |
||
8911 | |||
8912 | case tk_apiproc: |
||
8913 | |||
8914 | case tk_declare: |
||
8915 | |||
8916 | op(0x50); //push AX |
||
8917 | |||
8918 | unsigned char oaddstack; |
||
8919 | |||
8920 | addstack=FALSE; |
||
8921 | |||
8922 | addstack=oaddstack; |
||
8923 | |||
8924 | op66(razr); |
||
8925 | |||
8926 | op66(razr); |
||
8927 | |||
8928 | if(expand==FALSE)ClearDX(razr,sign); |
||
8929 | |||
8930 | op(0xF7); |
||
8931 | |||
8932 | else op(0xF0+ECX); /* DIV ECX */ |
||
8933 | |||
8934 | break; |
||
8935 | |||
8936 | case tk_seg: |
||
8937 | |||
8938 | case tk_beg: |
||
8939 | |||
8940 | case tk_rmnumber: |
||
8941 | |||
8942 | case tk_apioffset: |
||
8943 | |||
8944 | getintoreg_32(CX,razr,0,&ofsstr,FALSE); |
||
8945 | |||
8946 | op66(razr); |
||
8947 | |||
8948 | else outword(0xF1F7); /* DIV CX */ |
||
8949 | |||
8950 | warningreg(regs[razr/2-1][ECX]); |
||
8951 | |||
8952 | ClearReg(AX); |
||
8953 | |||
8954 | default: valueexpected(); break; |
||
8955 | |||
8956 | setzeroflag=FALSE; |
||
8957 | |||
8958 | op66(razr); |
||
8959 | |||
8960 | else op(0x92); //xchg ax,dx |
||
8961 | |||
8962 | } |
||
8963 | |||
8964 | } |
||
8965 | |||
8966 | void DivNum(unsigned long num,int razr,int sign) |
||
8967 | |||
8968 | /*int i; |
||
8969 | |||
8970 | if(num<65536&&optimizespeed&&(itok.flag&f_reloc)==0&&sign==0){ //for signed needed new algoritm |
||
8971 | |||
8972 | num2=65536/(unsigned int)num+1; |
||
8973 | |||
8974 | op66(r32); |
||
8975 | |||
8976 | outdword(0xffff); //and EAX,ffff |
||
8977 | |||
8978 | op66(r32); |
||
8979 | |||
8980 | op(0xc0); |
||
8981 | |||
8982 | else outdword(num2); |
||
8983 | |||
8984 | outword(0xE8C1); |
||
8985 | |||
8986 | setzeroflag=TRUE; |
||
8987 | |||
8988 | else{ |
||
8989 | |||
8990 | else num=65536/(unsigned int)num+1; |
||
8991 | |||
8992 | op(0xBA); //mov DX,num |
||
8993 | |||
8994 | else outdword(num); |
||
8995 | |||
8996 | outword(0xE2F7); //mul DX |
||
8997 | |||
8998 | outword(0xD089); //mov AX,DX |
||
8999 | |||
9000 | warningreg(regs[razr/2-1][2]); |
||
9001 | |||
9002 | return; |
||
9003 | |||
9004 | stddiv:*/ |
||
9005 | |||
9006 | DivNum2(num,razr,sign); |
||
9007 | |||
9008 | |||
9009 | |||
9010 | { |
||
9011 | |||
9012 | else{ |
||
9013 | |||
9014 | outword(0xD231); |
||
9015 | |||
9016 | warningreg(regs[razr/2-1][EDX]); |
||
9017 | |||
9018 | } |
||
9019 | |||
9020 | void DivNum2(unsigned long num,int razr,int sign) |
||
9021 | |||
9022 | MovRegNum(razr,itok.flag&f_reloc,num,ECX); |
||
9023 | |||
9024 | if(sign)outword(0xF9F7); /* IDIV CX */ |
||
9025 | |||
9026 | warningreg(regs[razr/2-1][ECX]); |
||
9027 | |||
9028 | ClearReg(AX); |
||
9029 | |||
9030 | |||
9031 | |||
9032 | { |
||
9033 | |||
9034 | int oline,oendinptr; |
||
9035 | |||
9036 | unsigned char *oinput; |
||
9037 | |||
9038 | int useeax=FALSE; |
||
9039 | |||
9040 | int rettype=tk_reg; |
||
9041 | |||
9042 | SINFO ostr; |
||
9043 | |||
9044 | int j=0; |
||
9045 | |||
9046 | COM_MOD *bmod; |
||
9047 | |||
9048 | case tk_ID: |
||
9049 | |||
9050 | case tk_proc: |
||
9051 | |||
9052 | case tk_undefproc: |
||
9053 | |||
9054 | break; |
||
9055 | |||
9056 | // if(cur_mod)break; //10.08.04 22:50 из-за define прекратить |
||
9057 | |||
9058 | bufrm=NULL; |
||
9059 | |||
9060 | strinf.bufstr=NULL; |
||
9061 | |||
9062 | oitok2=itok2; |
||
9063 | |||
9064 | otok2=tok2; |
||
9065 | |||
9066 | oinptr=inptr2; |
||
9067 | |||
9068 | oendinptr=endinptr; |
||
9069 | |||
9070 | while(bmod){ |
||
9071 | |||
9072 | bmod=bmod->next; |
||
9073 | |||
9074 | bmod=cur_mod; |
||
9075 | |||
9076 | // printf("input=%08X inptr=%08X %s\n",input,inptr2,input+inptr2); |
||
9077 | |||
9078 | while((!useeax)&&itok.type!=tp_stopper&&tok!=tk_eof){ |
||
9079 | |||
9080 | if(itok.type==tp_stopper)break; |
||
9081 | |||
9082 | else{ |
||
9083 | |||
9084 | if(bufrm){ free(bufrm); bufrm=NULL; } |
||
9085 | |||
9086 | switch(operand){ |
||
9087 | |||
9088 | case tk_mod: |
||
9089 | |||
9090 | case tk_modminus: |
||
9091 | |||
9092 | if((tok==tk_reg||tok==tk_reg32)&&itok.number==reg)useeax=TRUE; |
||
9093 | |||
9094 | if(tok==tk_number){ |
||
9095 | |||
9096 | } |
||
9097 | |||
9098 | j++; |
||
9099 | |||
9100 | } |
||
9101 | |||
9102 | break; |
||
9103 | |||
9104 | } |
||
9105 | |||
9106 | if(bmod!=cur_mod){ |
||
9107 | |||
9108 | cur_mod=bmod; |
||
9109 | |||
9110 | bmod->freze=FALSE; |
||
9111 | |||
9112 | } |
||
9113 | |||
9114 | else{ |
||
9115 | |||
9116 | COM_MOD *temp=cur_mod; |
||
9117 | |||
9118 | // printf("bmod=%08X cur_mod=%08X\n",bmod,cur_mod); |
||
9119 | |||
9120 | free(temp); |
||
9121 | |||
9122 | while(bmod){ |
||
9123 | |||
9124 | bmod=bmod->next; |
||
9125 | |||
9126 | } |
||
9127 | |||
9128 | } |
||
9129 | |||
9130 | itok=oitok; |
||
9131 | |||
9132 | tok=otok; |
||
9133 | |||
9134 | linenum2=oline; |
||
9135 | |||
9136 | cha2=ocha; |
||
9137 | |||
9138 | // printf("input=%08X inptr=%08X %s\n",input,inptr2,input+inptr2); |
||
9139 | |||
9140 | // if(strinf.bufstr)free(strinf.bufstr); |
||
9141 | |||
9142 | strinf=ostr; |
||
9143 | |||
9144 | } |
||
9145 | |||
9146 | op66(razr); |
||
9147 | |||
9148 | addESP+=razr==r16?2:4; |
||
9149 | |||
9150 | op66(razr); |
||
9151 | |||
9152 | op(0x89); |
||
9153 | |||
9154 | } |
||
9155 | |||
9156 | op66(razr); |
||
9157 | |||
9158 | op(0x58); |
||
9159 | |||
9160 | else{ |
||
9161 | |||
9162 | i=EAX; |
||
9163 | |||
9164 | } |
||
9165 | |||
9166 | rettype=getintoreg_32(i,razr,sign,ofsstr); |
||
9167 | |||
9168 | doregmath_32(reg,razr,sign,ofsstr,j); |
||
9169 | |||
9170 | } |
||
9171 | |||
9172 | return rettype; |
||
9173 | |||
9174 | |||
9175 | |||
9176 | { |
||
9177 | |||
9178 | char *wbuf; |
||
9179 | |||
9180 | int razr,i,sign=0,posiblret,pointr=0; |
||
9181 | |||
9182 | int numpointr=0; |
||
9183 | |||
9184 | posiblret=rettype=tk_dword; |
||
9185 | |||
9186 | i=itok.bit.siz+itok.bit.ofs; |
||
9187 | |||
9188 | razr=r8; |
||
9189 | |||
9190 | } |
||
9191 | |||
9192 | posiblret=rettype=tk_word; |
||
9193 | |||
9194 | } |
||
9195 | |||
9196 | if(tok2==tk_assign){ |
||
9197 | |||
9198 | strinf.bufstr=NULL; |
||
9199 | |||
9200 | wbuf=bufrm; |
||
9201 | |||
9202 | nexttok(); |
||
9203 | |||
9204 | convert_type(&sign,(int *)&rettype,&pointr); |
||
9205 | |||
9206 | nexttok(); |
||
9207 | |||
9208 | } |
||
9209 | |||
9210 | if(tok2==tk_assign){ |
||
9211 | |||
9212 | goto axtobit; |
||
9213 | |||
9214 | if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr); |
||
9215 | |||
9216 | if(tok==tk_number){ |
||
9217 | |||
9218 | if(!OnlyNumber(0))goto labl1; |
||
9219 | |||
9220 | } |
||
9221 | |||
9222 | unsigned long num=itok.number; |
||
9223 | |||
9224 | itok.number=num; |
||
9225 | |||
9226 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
9227 | |||
9228 | else{ |
||
9229 | |||
9230 | wtok.bit.siz=32-wtok.bit.ofs; |
||
9231 | |||
9232 | wtok.bit.siz=siz+wtok.bit.ofs-32; |
||
9233 | |||
9234 | itok.number=itok.number>>(32-wtok.bit.siz); |
||
9235 | |||
9236 | num2bits(&wtok,itok.number,r8); |
||
9237 | |||
9238 | } |
||
9239 | |||
9240 | labl1: |
||
9241 | |||
9242 | else if(rettype==tk_int||rettype==tk_word)do_e_axmath(sign,r16,&ofsstr); |
||
9243 | |||
9244 | else do_e_axmath(sign,r32,&ofsstr); |
||
9245 | |||
9246 | CheckAllMassiv(wbuf,razr,&wstr,&wtok); |
||
9247 | |||
9248 | if(razr!=r64)reg2bits(&wtok,razr); |
||
9249 | |||
9250 | int siz=wtok.bit.siz; |
||
9251 | |||
9252 | op(0x50); //push eax |
||
9253 | |||
9254 | addESP+=4; |
||
9255 | |||
9256 | reg2bits(&wtok,r32); |
||
9257 | |||
9258 | op(0x58); //pop eax |
||
9259 | |||
9260 | op66(r32); //shr eax,size |
||
9261 | |||
9262 | op(wtok.bit.siz); |
||
9263 | |||
9264 | wtok.bit.ofs=0; |
||
9265 | |||
9266 | reg2bits(&wtok,r8); |
||
9267 | |||
9268 | return; |
||
9269 | |||
9270 | } |
||
9271 | |||
9272 | bits2reg(AX,razr); |
||
9273 | |||
9274 | strinf.bufstr=NULL; |
||
9275 | |||
9276 | wbuf=bufrm; |
||
9277 | |||
9278 | switch(razr){ |
||
9279 | |||
9280 | dobeg(AL); |
||
9281 | |||
9282 | case r16: |
||
9283 | |||
9284 | doreg_32(AX,razr); |
||
9285 | |||
9286 | case r64: |
||
9287 | |||
9288 | break; |
||
9289 | |||
9290 | goto axtobit; |
||
9291 | |||
9292 | seminext(); |
||
9293 | |||
9294 | |||
9295 | |||
9296 | { |
||
9297 | |||
9298 | i=itok.bit.siz+itok.bit.ofs; |
||
9299 | |||
9300 | ITOK wtok; |
||
9301 | |||
9302 | wbuf=bufrm; |
||
9303 | |||
9304 | wtok=itok; |
||
9305 | |||
9306 | wstr=strinf; |
||
9307 | |||
9308 | switch(razr){ |
||
9309 | |||
9310 | if(reg==AL){ |
||
9311 | |||
9312 | if(i!=8){ |
||
9313 | |||
9314 | op(j); |
||
9315 | |||
9316 | } |
||
9317 | |||
9318 | CheckAllMassiv(bufrm,1,&strinf); |
||
9319 | |||
9320 | op(0x8A); |
||
9321 | |||
9322 | outaddress(&itok); |
||
9323 | |||
9324 | op(128); |
||
9325 | |||
9326 | op(j); |
||
9327 | |||
9328 | } |
||
9329 | |||
9330 | if(itok.bit.ofs==1){ |
||
9331 | |||
9332 | op(0xE8+reg); |
||
9333 | |||
9334 | else{ |
||
9335 | |||
9336 | op(0xE8+reg); |
||
9337 | |||
9338 | } |
||
9339 | |||
9340 | break; |
||
9341 | |||
9342 | case r32: |
||
9343 | |||
9344 | getinto_e_ax(0,(razr==r16?tk_wordvar:tk_dwordvar),&wtok,wbuf,&wstr,razr); |
||
9345 | |||
9346 | op66(razr); //and (e)ax,j |
||
9347 | |||
9348 | outword(j); |
||
9349 | |||
9350 | else if(razr==r32&&i!=32){ |
||
9351 | |||
9352 | if(short_ok(j,TRUE)){ |
||
9353 | |||
9354 | op(128+64+0x20); |
||
9355 | |||
9356 | } |
||
9357 | |||
9358 | op(4+1+0x20); |
||
9359 | |||
9360 | } |
||
9361 | |||
9362 | if(j<65536&&razr==r32)skip66=TRUE; |
||
9363 | |||
9364 | if(!skip66)op66(razr); |
||
9365 | |||
9366 | else{ |
||
9367 | |||
9368 | op(itok.bit.ofs); |
||
9369 | |||
9370 | } |
||
9371 | |||
9372 | else{ |
||
9373 | |||
9374 | if(!am32){ |
||
9375 | |||
9376 | reg1=reg; |
||
9377 | |||
9378 | } |
||
9379 | |||
9380 | else{ |
||
9381 | |||
9382 | if(reg==idxregs[1])reg2=idxregs[0]; |
||
9383 | |||
9384 | CheckAllMassiv(bufrm,razr==r32?4:2,&strinf,&itok,reg1,reg2); |
||
9385 | |||
9386 | outseg(&itok,2); |
||
9387 | |||
9388 | op(reg*8+itok.rm); |
||
9389 | |||
9390 | if((razr==r16&&i!=16)||(razr==r32&&i!=32)){ |
||
9391 | |||
9392 | if(short_ok(j,razr==r16?FALSE:TRUE)){ |
||
9393 | |||
9394 | op(128+64+reg+0x20); |
||
9395 | |||
9396 | } |
||
9397 | |||
9398 | op(128+1); |
||
9399 | |||
9400 | if(razr==r16)outword(j); |
||
9401 | |||
9402 | } |
||
9403 | |||
9404 | if(itok.bit.ofs){ //shr reg,ofs |
||
9405 | |||
9406 | if(itok.bit.ofs==1){ |
||
9407 | |||
9408 | op(0xE8+reg); |
||
9409 | |||
9410 | else{ |
||
9411 | |||
9412 | op(0xE8+reg); |
||
9413 | |||
9414 | } |
||
9415 | |||
9416 | } |
||
9417 | |||
9418 | case r64: |
||
9419 | |||
9420 | getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32); |
||
9421 | |||
9422 | outseg(&itok,2); |
||
9423 | |||
9424 | op(DX*8+itok.rm); |
||
9425 | |||
9426 | if(itok.bit.siz!=32){ |
||
9427 | |||
9428 | op(128+64+DL+0x20); |
||
9429 | |||
9430 | } |
||
9431 | |||
9432 | outword(0xAC0F); //shrd edx,eax,ofs |
||
9433 | |||
9434 | op(itok.bit.ofs); |
||
9435 | |||
9436 | warningreg(regs[1][EDX]); |
||
9437 | |||
9438 | else{ |
||
9439 | |||
9440 | if(reg==DX)reg1=CX; |
||
9441 | |||
9442 | op66(r32); |
||
9443 | |||
9444 | op(0x8B); |
||
9445 | |||
9446 | outaddress(&itok); |
||
9447 | |||
9448 | outseg(&itok,2); |
||
9449 | |||
9450 | op(reg1*8+itok.rm); |
||
9451 | |||
9452 | if(itok.bit.siz!=32){ |
||
9453 | |||
9454 | op(128+64+reg1+0x20); |
||
9455 | |||
9456 | } |
||
9457 | |||
9458 | op66(r32); |
||
9459 | |||
9460 | op(0xc0+reg1+reg*8); |
||
9461 | |||
9462 | warningreg(regs[1][reg1]); |
||
9463 | |||
9464 | ClearReg(DX); |
||
9465 | |||
9466 | } |
||
9467 | |||
9468 | ClearReg(reg); |
||
9469 | |||
9470 | |||
9471 | |||
9472 | { |
||
9473 | |||
9474 | mask=GetBitMask(gtok->bit.ofs,gtok->bit.siz); |
||
9475 | |||
9476 | if((num&j)!=j){ |
||
9477 | |||
9478 | op66(razr); //and bits,mask |
||
9479 | |||
9480 | if((postnumflag&f_reloc)==0&&short_ok(mask,razr/2-1)){ |
||
9481 | |||
9482 | op(gtok->rm+0x20); |
||
9483 | |||
9484 | op(mask); |
||
9485 | |||
9486 | else{ |
||
9487 | |||
9488 | op(gtok->rm+0x20); |
||
9489 | |||
9490 | if((postnumflag&f_reloc)!=0)AddReloc(); |
||
9491 | |||
9492 | else outdword(mask); |
||
9493 | |||
9494 | } |
||
9495 | |||
9496 | outseg(gtok,2); //and bits,mask |
||
9497 | |||
9498 | op(gtok->rm+0x20); |
||
9499 | |||
9500 | op(mask); |
||
9501 | |||
9502 | } |
||
9503 | |||
9504 | if(num<65536&&razr==r32)razr=r16; |
||
9505 | |||
9506 | if(razr!=r8){ |
||
9507 | |||
9508 | outseg(gtok,2); |
||
9509 | |||
9510 | op(128+2+1); |
||
9511 | |||
9512 | outaddress(gtok); |
||
9513 | |||
9514 | } |
||
9515 | |||
9516 | op(128+1); |
||
9517 | |||
9518 | outaddress(gtok); |
||
9519 | |||
9520 | if(razr==r16)outword(num); |
||
9521 | |||
9522 | } |
||
9523 | |||
9524 | else{ |
||
9525 | |||
9526 | outseg(gtok,2); |
||
9527 | |||
9528 | op(gtok->rm+8); |
||
9529 | |||
9530 | op(num); |
||
9531 | |||
9532 | } |
||
9533 | |||
9534 | |||
9535 | |||
9536 | { |
||
9537 | |||
9538 | j=li[gtok->bit.siz]-1; |
||
9539 | |||
9540 | i=gtok->bit.ofs+gtok->bit.siz; |
||
9541 | |||
9542 | case r8: |
||
9543 | |||
9544 | op(4+0x20); //and al,size |
||
9545 | |||
9546 | } |
||
9547 | |||
9548 | op(128); |
||
9549 | |||
9550 | outaddress(gtok); |
||
9551 | |||
9552 | if(gtok->bit.ofs)lshiftmul(gtok->bit.ofs,razr); |
||
9553 | |||
9554 | op(8); |
||
9555 | |||
9556 | outaddress(gtok); |
||
9557 | |||
9558 | case r16: |
||
9559 | |||
9560 | if(razr==r16&&i!=16){ |
||
9561 | |||
9562 | op(4+1+0x20); |
||
9563 | |||
9564 | } |
||
9565 | |||
9566 | op66(razr); //and (e)ax,size |
||
9567 | |||
9568 | op(128+2+1); |
||
9569 | |||
9570 | op((int)j); |
||
9571 | |||
9572 | else{ |
||
9573 | |||
9574 | outdword(j); |
||
9575 | |||
9576 | } |
||
9577 | |||
9578 | outseg(gtok,2); |
||
9579 | |||
9580 | op(128+2+1); |
||
9581 | |||
9582 | outaddress(gtok); |
||
9583 | |||
9584 | } |
||
9585 | |||
9586 | op(128+1); |
||
9587 | |||
9588 | outaddress(gtok); |
||
9589 | |||
9590 | else outdword(mask); |
||
9591 | |||
9592 | if(gtok->bit.ofs)lshiftmul(gtok->bit.ofs,razr); |
||
9593 | |||
9594 | outseg(gtok,2); |
||
9595 | |||
9596 | op(gtok->rm); |
||
9597 | |||
9598 | break; |
||
9599 | |||
9600 | } |
||
9601 | |||
9602 | void getoperand(int reg) |
||
9603 | |||
9604 | unsigned int numpointr=0; |
||
9605 | |||
9606 | while(tok==tk_mult){ |
||
9607 | |||
9608 | numpointr++; |
||
9609 | |||
9610 | if(numpointr>itok.npointr){ |
||
9611 | |||
9612 | } |
||
9613 | |||
9614 | cpointr(reg,numpointr); |
||
9615 | |||
9616 | CheckMinusNum(); |
||
9617 | |||
9618 | |||
9619 | |||
9620 | { |
||
9621 | |||
9622 | if(tok2==tk_openbracket){ |
||
9623 | |||
9624 | } |
||
9625 | |||
9626 | itok.rm=itok.sib; |
||
9627 | |||
9628 | itok.sib=CODE32; |
||
9629 | |||
9630 | } |
||
9631 | |||
9632 | |||
9633 | |||
9634 | } |
||
9635 | |||
9636 | |||
9637 | |||
9638 | } |
||
9639 | |||
9640 | if(numpointr==itok.npointr){ |
||
9641 | |||
9642 | if(itok.type>=tk_char&&itok.type<=tk_float)tok=tk_charvar+itok.type-tk_char; |
||
9643 | |||
9644 | } |
||
9645 | |||
9646 | if(numpointr)getpointeradr(&itok,bufrm,&strinf,numpointr-1,razr,reg); |
||
9647 | |||
9648 | } |
||
9649 | |||
9650 | } |
||
9651 | |||
9652 | void cwpointr(ITOK *wtok,char *&wbuf,SINFO *wstr,int *otok,int npointr,int ureg) |
||
9653 | |||
9654 | if(wtok->type==tk_proc){ |
||
9655 | |||
9656 | if(am32){ |
||
9657 | |||
9658 | *otok=tk_dwordvar; |
||
9659 | |||
9660 | else{ |
||
9661 | |||
9662 | *otok=tk_wordvar; |
||
9663 | |||
9664 | compressoffset(wtok); |
||
9665 | |||
9666 | else{ |
||
9667 | |||
9668 | int reg=idxregs[2]; |
||
9669 | |||
9670 | if(npointr==wtok->npointr){ |
||
9671 | |||
9672 | if(wtok->type>=tk_char&&wtok->type<=tk_float)*otok=tk_charvar+wtok->type-tk_char; |
||
9673 | |||
9674 | } |
||
9675 | |||
9676 | *otok=(am32==FALSE?tk_wordvar:tk_dwordvar); |
||
9677 | |||
9678 | else return; |
||
9679 | |||
9680 | else unuseableinput(); |
||
9681 | |||
9682 | } |
||
9683 | |||
9684 | |||
9685 | |||
9686 | { |
||
9687 | |||
9688 | int oline; |
||
9689 | |||
9690 | unsigned char ocha; |
||
9691 | |||
9692 | SINFO ostr; |
||
9693 | |||
9694 | int j=3; |
||
9695 | |||
9696 | if(tok==tk_minusequals)changesign++; |
||
9697 | |||
9698 | if(itok2.type==tp_stopper)return FALSE; |
||
9699 | |||
9700 | obuf=bufrm; |
||
9701 | |||
9702 | ostr=strinf; |
||
9703 | |||
9704 | oitok=itok; |
||
9705 | |||
9706 | otok=tok; |
||
9707 | |||
9708 | oline=linenum2; |
||
9709 | |||
9710 | ocha=cha2; |
||
9711 | |||
9712 | while(itok.type!=tp_stopper&&tok!=tk_eof){ |
||
9713 | |||
9714 | switch(tok){ |
||
9715 | |||
9716 | case tk_id: |
||
9717 | |||
9718 | case tk_apiproc: |
||
9719 | |||
9720 | case tk_declare: |
||
9721 | |||
9722 | itok.type=tp_stopper; |
||
9723 | |||
9724 | } |
||
9725 | |||
9726 | if(itok.type==tp_opperand){ |
||
9727 | |||
9728 | retval=FALSE; |
||
9729 | |||
9730 | } |
||
9731 | |||
9732 | int i=inptr2-1; |
||
9733 | |||
9734 | do{ |
||
9735 | |||
9736 | c=input[i]; |
||
9737 | |||
9738 | }while(c!='-'&&c!='+'); |
||
9739 | |||
9740 | if(c=='-')c='+'; |
||
9741 | |||
9742 | input[i]=c; |
||
9743 | |||
9744 | while(itok2.type==tp_opperand&&tok!=tk_eof)nexttok(); |
||
9745 | |||
9746 | else{ |
||
9747 | |||
9748 | if(j>1)j=0; |
||
9749 | |||
9750 | if(strinf.bufstr)free(strinf.bufstr); |
||
9751 | |||
9752 | else if(j>1)j--; |
||
9753 | |||
9754 | } |
||
9755 | |||
9756 | itok2=oitok2; |
||
9757 | |||
9758 | tok2=otok2; |
||
9759 | |||
9760 | inptr2=oinptr; |
||
9761 | |||
9762 | endoffile=0; |
||
9763 | |||
9764 | strinf=ostr; |
||
9765 | |||
9766 | else if(changesign==1){ |
||
9767 | |||
9768 | goto newloop; |
||
9769 | |||
9770 | return retval; |
||
9771 | |||
9772 | |||
9773 | |||
9774 | { |
||
9775 | |||
9776 | unsigned int vop=0,otok,rettype; |
||
9777 | |||
9778 | ITOK wtok; |
||
9779 | |||
9780 | SINFO wstr; |
||
9781 | |||
9782 | int numpointr=0; |
||
9783 | |||
9784 | char *ofsstr=NULL; |
||
9785 | |||
9786 | rettype=tk_qword; |
||
9787 | |||
9788 | wstr=strinf; |
||
9789 | |||
9790 | wtok=itok; |
||
9791 | |||
9792 | bufrm=NULL; |
||
9793 | |||
9794 | nexttok(); |
||
9795 | |||
9796 | case tk_assign: //= |
||
9797 | |||
9798 | convert_type(&sign,(int *)&rettype,&pointr); |
||
9799 | |||
9800 | nexttok(); |
||
9801 | |||
9802 | } |
||
9803 | |||
9804 | unuseableinput(); |
||
9805 | |||
9806 | CheckMinusNum(); |
||
9807 | |||
9808 | if(tok==tk_number){ //проверка и суммирование чисел |
||
9809 | |||
9810 | case tk_float: sign=2; break; |
||
9811 | |||
9812 | case tk_qword: sign=4; break; |
||
9813 | |||
9814 | if(OnlyNumber(sign)){ |
||
9815 | |||
9816 | itok.flag=(unsigned char)postnumflag; |
||
9817 | |||
9818 | } |
||
9819 | |||
9820 | goto labl1; |
||
9821 | |||
9822 | else{ |
||
9823 | |||
9824 | case tk_number: |
||
9825 | |||
9826 | if(itok.lnumber==0){ |
||
9827 | |||
9828 | for(i=0;i<2;i++){ |
||
9829 | |||
9830 | outseg(&wtok,2); |
||
9831 | |||
9832 | op(wtok.rm+0x20); |
||
9833 | |||
9834 | op(0); |
||
9835 | |||
9836 | wtok.number+=4; |
||
9837 | |||
9838 | } |
||
9839 | |||
9840 | } |
||
9841 | |||
9842 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
9843 | |||
9844 | op66(r32); |
||
9845 | |||
9846 | op(0x83); |
||
9847 | |||
9848 | outaddress(&wtok); |
||
9849 | |||
9850 | if(i==1)break; |
||
9851 | |||
9852 | compressoffset(&wtok); |
||
9853 | |||
9854 | break; |
||
9855 | |||
9856 | } |
||
9857 | |||
9858 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
9859 | |||
9860 | op66(r32); |
||
9861 | |||
9862 | op(0x6A); |
||
9863 | |||
9864 | op66(r32); |
||
9865 | |||
9866 | op(0x8f); |
||
9867 | |||
9868 | outaddress(&wtok); |
||
9869 | |||
9870 | else{ |
||
9871 | |||
9872 | op(0xC7); //mov word[],number |
||
9873 | |||
9874 | outaddress(&wtok); |
||
9875 | |||
9876 | outdword(itok.number); |
||
9877 | |||
9878 | if(i==1)break; |
||
9879 | |||
9880 | wtok.number+=4; |
||
9881 | |||
9882 | } |
||
9883 | |||
9884 | case tk_apioffset: |
||
9885 | |||
9886 | case tk_undefofs: |
||
9887 | |||
9888 | op66(r32); |
||
9889 | |||
9890 | op(0xC7); //mov word[],number |
||
9891 | |||
9892 | outaddress(&wtok); |
||
9893 | |||
9894 | else{ |
||
9895 | |||
9896 | else if(tok==tk_undefofs)AddUndefOff(0,itok.name); |
||
9897 | |||
9898 | outdword(itok.number); |
||
9899 | |||
9900 | wtok.number+=4; |
||
9901 | |||
9902 | op66(r32); |
||
9903 | |||
9904 | op(0x83); |
||
9905 | |||
9906 | outaddress(&wtok); |
||
9907 | |||
9908 | break; |
||
9909 | |||
9910 | goto getfromreg; |
||
9911 | |||
9912 | if(itok.number==AX&&wbuf==NULL&&wstr.bufstr==NULL&& |
||
9913 | |||
9914 | (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
9915 | |||
9916 | outseg(&wtok,1); |
||
9917 | |||
9918 | if(wtok.post==UNDEF_OFSET){ |
||
9919 | |||
9920 | wtok.post=0; |
||
9921 | |||
9922 | if(am32==FALSE)outword(wtok.number); |
||
9923 | |||
9924 | } |
||
9925 | |||
9926 | CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); |
||
9927 | |||
9928 | outseg(&wtok,2); |
||
9929 | |||
9930 | op((unsigned int)itok.number*8+wtok.rm); |
||
9931 | |||
9932 | } |
||
9933 | |||
9934 | compressoffset(&wtok); |
||
9935 | |||
9936 | outseg(&wtok,2); |
||
9937 | |||
9938 | op(wtok.rm+0x20); |
||
9939 | |||
9940 | op(0); |
||
9941 | |||
9942 | case tk_string: |
||
9943 | |||
9944 | op66(r32); |
||
9945 | |||
9946 | op(0xC7); |
||
9947 | |||
9948 | outaddress(&wtok); |
||
9949 | |||
9950 | wtok.number+=4; |
||
9951 | |||
9952 | op66(r32); |
||
9953 | |||
9954 | op(0x83); |
||
9955 | |||
9956 | outaddress(&wtok); |
||
9957 | |||
9958 | break; |
||
9959 | |||
9960 | labl1: |
||
9961 | |||
9962 | getintoreg64(reg); |
||
9963 | |||
9964 | getfromAX=1; |
||
9965 | |||
9966 | break; |
||
9967 | |||
9968 | } |
||
9969 | |||
9970 | getfromax: |
||
9971 | |||
9972 | getfromreg: |
||
9973 | |||
9974 | for(i=0;i<2;i++){ |
||
9975 | |||
9976 | ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| |
||
9977 | |||
9978 | op66(r32); |
||
9979 | |||
9980 | op(0xA3); // MOV [word],AX |
||
9981 | |||
9982 | AddUndefOff(2,wtok.name); |
||
9983 | |||
9984 | } |
||
9985 | |||
9986 | else outdword(wtok.number); |
||
9987 | |||
9988 | else{ |
||
9989 | |||
9990 | op66(r32); |
||
9991 | |||
9992 | op(0x89); |
||
9993 | |||
9994 | outaddress(&wtok); |
||
9995 | |||
9996 | if(i==1)break; |
||
9997 | |||
9998 | compressoffset(&wtok); |
||
9999 | |||
10000 | } |
||
10001 | |||
10002 | warningreg(regs[1][EDX]); |
||
10003 | |||
10004 | ClearReg(DX); |
||
10005 | |||
10006 | } |
||
10007 | |||
10008 | case tk_minusminus: vop=0x8; |
||
10009 | |||
10010 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10011 | |||
10012 | outseg(&wtok,2); |
||
10013 | |||
10014 | op(0xFF); op(vop+wtok.rm); |
||
10015 | |||
10016 | wtok.number+=4; |
||
10017 | |||
10018 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10019 | |||
10020 | outseg(&wtok,2); |
||
10021 | |||
10022 | outaddress(&wtok); |
||
10023 | |||
10024 | break; |
||
10025 | |||
10026 | case tk_minusequals: vop+=0x08; |
||
10027 | |||
10028 | case tk_orequals: vop+=0x08; |
||
10029 | |||
10030 | getoperand(am32==TRUE?EAX:BX); |
||
10031 | |||
10032 | if(tok==tk_number){ |
||
10033 | |||
10034 | next=0; |
||
10035 | |||
10036 | tok=tk_number; |
||
10037 | |||
10038 | } |
||
10039 | |||
10040 | goto defxor; |
||
10041 | |||
10042 | else{ |
||
10043 | |||
10044 | case tk_number: |
||
10045 | |||
10046 | case tk_undefofs: |
||
10047 | |||
10048 | num: |
||
10049 | |||
10050 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10051 | |||
10052 | outseg(&wtok,2); |
||
10053 | |||
10054 | if(i==0&&itok.lnumber==1){ |
||
10055 | |||
10056 | if(next==0)tok=otok; |
||
10057 | |||
10058 | } |
||
10059 | |||
10060 | op(0xFF); op((vop!=0?8:0)+wtok.rm); |
||
10061 | |||
10062 | goto conl; |
||
10063 | |||
10064 | } |
||
10065 | |||
10066 | if(vop==0)vop+=0x10; |
||
10067 | |||
10068 | } |
||
10069 | |||
10070 | short_ok(itok.number,TRUE)){ |
||
10071 | |||
10072 | op(vop+wtok.rm); |
||
10073 | |||
10074 | op((unsigned int)itok.number); |
||
10075 | |||
10076 | else{ |
||
10077 | |||
10078 | op(vop+wtok.rm); |
||
10079 | |||
10080 | if(tok==tk_apioffset)AddApiToPost(itok.number); |
||
10081 | |||
10082 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
10083 | |||
10084 | else if((itok.flag&f_reloc)!=0)AddReloc(); |
||
10085 | |||
10086 | } |
||
10087 | |||
10088 | conl: |
||
10089 | |||
10090 | compressoffset(&wtok); |
||
10091 | |||
10092 | } |
||
10093 | |||
10094 | break; |
||
10095 | |||
10096 | reg=itok.number&255; |
||
10097 | |||
10098 | if(i==1){ |
||
10099 | |||
10100 | else if(vop==0x28)vop-=0x10; |
||
10101 | |||
10102 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10103 | |||
10104 | outseg(&wtok,2); |
||
10105 | |||
10106 | outaddress(&wtok); |
||
10107 | |||
10108 | wtok.number+=4; |
||
10109 | |||
10110 | reg=itok.number/256; |
||
10111 | |||
10112 | break; |
||
10113 | |||
10114 | defxor: |
||
10115 | |||
10116 | getintoreg64(reg); |
||
10117 | |||
10118 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10119 | |||
10120 | for(i=0;i<2;i++){ |
||
10121 | |||
10122 | op(0x01+vop); |
||
10123 | |||
10124 | outaddress(&wtok); |
||
10125 | |||
10126 | if(vop==0)vop=0x10; |
||
10127 | |||
10128 | reg=EDX; |
||
10129 | |||
10130 | compressoffset(&wtok); |
||
10131 | |||
10132 | next=0; |
||
10133 | |||
10134 | warningreg(regs[1][EAX]); |
||
10135 | |||
10136 | break; |
||
10137 | |||
10138 | } |
||
10139 | |||
10140 | case tk_multequals: |
||
10141 | |||
10142 | if(itok2.type==tp_stopper&&tok==tk_number&&(itok.flag&f_reloc)==0){ |
||
10143 | |||
10144 | if(itok.lnumber==0){ |
||
10145 | |||
10146 | ZeroReg(EDX,r32); |
||
10147 | |||
10148 | } |
||
10149 | |||
10150 | if(wbuf==NULL&&wstr.bufstr==NULL&& |
||
10151 | |||
10152 | (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
10153 | |||
10154 | outseg(&wtok,1); |
||
10155 | |||
10156 | if(wtok.post==UNDEF_OFSET){ |
||
10157 | |||
10158 | wtok.post=0; |
||
10159 | |||
10160 | if(am32==FALSE)outword(wtok.number); |
||
10161 | |||
10162 | } |
||
10163 | |||
10164 | CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); |
||
10165 | |||
10166 | outseg(&wtok,2); |
||
10167 | |||
10168 | op(wtok.rm); |
||
10169 | |||
10170 | } |
||
10171 | |||
10172 | compressoffset(&wtok); |
||
10173 | |||
10174 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10175 | |||
10176 | outseg(&wtok,3); |
||
10177 | |||
10178 | op(0xA4+vop); |
||
10179 | |||
10180 | outaddress(&wtok); |
||
10181 | |||
10182 | wtok.number-=4; |
||
10183 | |||
10184 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10185 | |||
10186 | outseg(&wtok,2); |
||
10187 | |||
10188 | op(0x20+wtok.rm); |
||
10189 | |||
10190 | op(i); |
||
10191 | |||
10192 | } |
||
10193 | |||
10194 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10195 | |||
10196 | compressoffset(&wtok); |
||
10197 | |||
10198 | op66(r32); |
||
10199 | |||
10200 | op(0xFF); op(0x30+wtok.rm); |
||
10201 | |||
10202 | if(i==1)break; |
||
10203 | |||
10204 | compressoffset(&wtok); |
||
10205 | |||
10206 | reg=ECX|(EAX*256); |
||
10207 | |||
10208 | doregmath64(reg); |
||
10209 | |||
10210 | next=0; |
||
10211 | |||
10212 | case tk_divequals: |
||
10213 | |||
10214 | if(itok2.type==tp_stopper&&tok==tk_number&&(itok.flag&f_reloc)==0){ |
||
10215 | |||
10216 | DevideZero(); |
||
10217 | |||
10218 | } |
||
10219 | |||
10220 | if((i=caselong(itok.number))!=NUMNUM){ |
||
10221 | |||
10222 | compressoffset(&wtok); |
||
10223 | |||
10224 | ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| |
||
10225 | |||
10226 | op66(r32); |
||
10227 | |||
10228 | op(0xA1); // MOV EAX,[dword] |
||
10229 | |||
10230 | AddUndefOff(2,wtok.name); |
||
10231 | |||
10232 | } |
||
10233 | |||
10234 | else outdword(wtok.number); |
||
10235 | |||
10236 | else{ |
||
10237 | |||
10238 | op66(r32); |
||
10239 | |||
10240 | op(0x8B); |
||
10241 | |||
10242 | outaddress(&wtok); |
||
10243 | |||
10244 | wtok.number-=4; |
||
10245 | |||
10246 | ClearReg(AX); |
||
10247 | |||
10248 | op66(r32); |
||
10249 | |||
10250 | op(0x0F); |
||
10251 | |||
10252 | op(wtok.rm); // SHLD [rmword],CL |
||
10253 | |||
10254 | op(i); |
||
10255 | |||
10256 | compressoffset(&wtok); |
||
10257 | |||
10258 | op66(r32); |
||
10259 | |||
10260 | op(0xC1); |
||
10261 | |||
10262 | outaddress(&wtok); |
||
10263 | |||
10264 | break; |
||
10265 | |||
10266 | unsigned long number; |
||
10267 | |||
10268 | for(i=0;i<2;i++){ |
||
10269 | |||
10270 | if((itok.flag&f_reloc)==0&&short_ok(number,1)){ |
||
10271 | |||
10272 | op(number); |
||
10273 | |||
10274 | else{ |
||
10275 | |||
10276 | if(i==0&&(itok.flag&f_reloc)!=0)AddReloc(); |
||
10277 | |||
10278 | } |
||
10279 | |||
10280 | number=itok.number; |
||
10281 | |||
10282 | goto divcont; |
||
10283 | |||
10284 | reg=EAX|(EDX*256); |
||
10285 | |||
10286 | doregmath64(reg); |
||
10287 | |||
10288 | op(0x50+EDX); |
||
10289 | |||
10290 | op(0x50+EAX); |
||
10291 | |||
10292 | divcont: |
||
10293 | |||
10294 | if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; |
||
10295 | |||
10296 | for(i=0;i<2;i++){ |
||
10297 | |||
10298 | ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| |
||
10299 | |||
10300 | op66(r32); |
||
10301 | |||
10302 | op(0xA1); |
||
10303 | |||
10304 | AddUndefOff(2,wtok.name); |
||
10305 | |||
10306 | if(am32==FALSE)outword(wtok.number); |
||
10307 | |||
10308 | } |
||
10309 | |||
10310 | CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); |
||
10311 | |||
10312 | outseg(&wtok,2); |
||
10313 | |||
10314 | op(reg*8+wtok.rm); |
||
10315 | |||
10316 | } |
||
10317 | |||
10318 | wtok.number+=4; |
||
10319 | |||
10320 | reg=EDX; |
||
10321 | |||
10322 | CallExternProc("__lludiv"); |
||
10323 | |||
10324 | wtok.number-=4; |
||
10325 | |||
10326 | goto getfromax; |
||
10327 | |||
10328 | int regdi; |
||
10329 | |||
10330 | getoperand(); |
||
10331 | |||
10332 | bufrm=NULL; |
||
10333 | |||
10334 | switch(tok){ |
||
10335 | |||
10336 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10337 | |||
10338 | for(i=0;i<2;i++){ |
||
10339 | |||
10340 | outseg(&wtok,2); |
||
10341 | |||
10342 | op(reg*8+wtok.rm); |
||
10343 | |||
10344 | ClearReg(reg); |
||
10345 | |||
10346 | reg=itok.number/256; |
||
10347 | |||
10348 | compressoffset(&wtok); |
||
10349 | |||
10350 | break; |
||
10351 | |||
10352 | for(i=0;i<2;i++){ |
||
10353 | |||
10354 | CheckAllMassiv(rbuf,8,&strinf,&itok,regdi==FALSE?BX:DI,DX); |
||
10355 | |||
10356 | outseg(&itok,2); |
||
10357 | |||
10358 | op(itok.rm); |
||
10359 | |||
10360 | KillVar(itok.name); |
||
10361 | |||
10362 | ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| |
||
10363 | |||
10364 | op66(r32); |
||
10365 | |||
10366 | op(0xA3); /* MOV [word],AX */ |
||
10367 | |||
10368 | AddUndefOff(2,wtok.name); |
||
10369 | |||
10370 | } |
||
10371 | |||
10372 | else outdword(wtok.number); |
||
10373 | |||
10374 | else{ |
||
10375 | |||
10376 | op66(r32); |
||
10377 | |||
10378 | op(0x89); op(wtok.rm); /* MOV [rmword],AX */ |
||
10379 | |||
10380 | } |
||
10381 | |||
10382 | itok.number+=4; |
||
10383 | |||
10384 | wtok.number+=4; |
||
10385 | |||
10386 | } |
||
10387 | |||
10388 | ClearReg(EAX); |
||
10389 | |||
10390 | default: swaperror(); break; |
||
10391 | |||
10392 | break; |
||
10393 | |||
10394 | vop=8; |
||
10395 | |||
10396 | compressoffset(&wtok); |
||
10397 | |||
10398 | getoperand(am32==TRUE?ECX:BX); |
||
10399 | |||
10400 | getintobeg(CL,&ofsstr); |
||
10401 | |||
10402 | warningreg(begs[1]); |
||
10403 | |||
10404 | i=1; |
||
10405 | |||
10406 | else if(tok==tk_number){ |
||
10407 | |||
10408 | } |
||
10409 | |||
10410 | if(tok!=tk_beg||(unsigned int)itok.number!=CL){ |
||
10411 | |||
10412 | ClearReg(CX); |
||
10413 | |||
10414 | next=0; |
||
10415 | |||
10416 | i=1; |
||
10417 | |||
10418 | if(wbuf==NULL&&wstr.bufstr==NULL&& |
||
10419 | |||
10420 | (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ |
||
10421 | |||
10422 | outseg(&wtok,1); |
||
10423 | |||
10424 | if(wtok.post==UNDEF_OFSET){ |
||
10425 | |||
10426 | wtok.post=0; |
||
10427 | |||
10428 | if(am32==FALSE)outword(wtok.number); |
||
10429 | |||
10430 | } |
||
10431 | |||
10432 | CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); |
||
10433 | |||
10434 | outseg(&wtok,2); |
||
10435 | |||
10436 | op(wtok.rm); |
||
10437 | |||
10438 | } |
||
10439 | |||
10440 | else wtok.number+=4; |
||
10441 | |||
10442 | ClearReg(AX); |
||
10443 | |||
10444 | CheckAllMassiv(wbuf,8,&wstr,&wtok); |
||
10445 | |||
10446 | outseg(&wtok,3); |
||
10447 | |||
10448 | op(0xA4+vop+i); |
||
10449 | |||
10450 | outaddress(&wtok); |
||
10451 | |||
10452 | if(vop)wtok.number+=4; |
||
10453 | |||
10454 | compressoffset(&wtok); |
||
10455 | |||
10456 | op66(r32); |
||
10457 | |||
10458 | op(i==0?0xC1:0xD3); |
||
10459 | |||
10460 | outaddress(&wtok); |
||
10461 | |||
10462 | break; |
||
10463 | |||
10464 | } |
||
10465 | |||
10466 | if(next)nexttok(); |
||
10467 | |||
10468 | if(cpu<3)cpu=3; |
||
10469 | |||
10470 | } |
||
10471 | |||
10472 | void Select2FreeReg(int r1,int r2,int *reg1,int *reg2) |
||
10473 | |||
10474 | *reg1=idxregs[0]; |
||
10475 | |||
10476 | if(r1==idxregs[0]){ |
||
10477 | |||
10478 | *reg1=idxregs[2]; |
||
10479 | |||
10480 | } |
||
10481 | |||
10482 | *reg1=idxregs[1]; |
||
10483 | |||
10484 | else *reg2=idxregs[2]; |
||
10485 | |||
10486 | } |
||
10487 | |||
10488 | if(r2==idxregs[0]){ |
||
10489 | |||
10490 | *reg2=idxregs[3]; |
||
10491 | |||
10492 | else{ |
||
10493 | |||
10494 | if(r2==idxregs[2])*reg2=idxregs[3]; |
||
10495 | |||
10496 | } |
||
10497 | |||
10498 | } |
||
10499 | |||
10500 | void doreg64(int reg,int terminater) |
||
10501 | |||
10502 | unsigned char next=1; |
||
10503 | |||
10504 | int i; |
||
10505 | |||
10506 | unsigned long long ii; |
||
10507 | |||
10508 | char *ofsstr=NULL; |
||
10509 | |||
10510 | int pointr=0; |
||
10511 | |||
10512 | rettype=tk_qword; |
||
10513 | |||
10514 | r2=reg/256; |
||
10515 | |||
10516 | if(r1==ESP||r2==ESP)RestoreStack(); |
||
10517 | |||
10518 | switch(tok){ |
||
10519 | |||
10520 | nexttok(); |
||
10521 | |||
10522 | |||
10523 | |||
10524 | convert_type(&sign,(int *)&rettype,&pointr); |
||
10525 | |||
10526 | nexttok(); |
||
10527 | |||
10528 | } |
||
10529 | |||
10530 | unuseableinput(); |
||
10531 | |||
10532 | CheckMinusNum(); |
||
10533 | |||
10534 | switch(rettype){ |
||
10535 | |||
10536 | case tk_double: sign=3; break; |
||
10537 | |||
10538 | } |
||
10539 | |||
10540 | MovRegNum(r32,postnumflag&f_reloc,itok.number,r1); |
||
10541 | |||
10542 | next=0; |
||
10543 | |||
10544 | } |
||
10545 | |||
10546 | if(rettype==tk_float||rettype==tk_double){ |
||
10547 | |||
10548 | op66(r32); |
||
10549 | |||
10550 | op66(r32); |
||
10551 | |||
10552 | op(0x31); op(0xC0+r2*9); |
||
10553 | |||
10554 | else op(0x58+r2); |
||
10555 | |||
10556 | break; |
||
10557 | |||
10558 | /*-----------------31.08.05 18:39------------------- |
||
10559 | |||
10560 | --------------------------------------------------*/ |
||
10561 | |||
10562 | doregmath64(reg); |
||
10563 | |||
10564 | break; |
||
10565 | |||
10566 | op66(r32); |
||
10567 | |||
10568 | op(0xD0+r2); |
||
10569 | |||
10570 | break; |
||
10571 | |||
10572 | op66(r32); |
||
10573 | |||
10574 | op(0xD8+r2); |
||
10575 | |||
10576 | break; |
||
10577 | |||
10578 | getoperand(reg1); |
||
10579 | |||
10580 | case tk_qwordvar: |
||
10581 | |||
10582 | for(i=0;i<2;i++){ |
||
10583 | |||
10584 | op66(r32); |
||
10585 | |||
10586 | op(0x87); |
||
10587 | |||
10588 | outaddress(&itok); |
||
10589 | |||
10590 | compressoffset(&itok); |
||
10591 | |||
10592 | } |
||
10593 | |||
10594 | case tk_reg64: |
||
10595 | |||
10596 | vop=itok.number; |
||
10597 | |||
10598 | for(i=0;i<2;i++){ |
||
10599 | |||
10600 | if(RegSwapReg(reg,itok.number,r32)==NOINREG){; |
||
10601 | |||
10602 | if(reg==AX)op(0x90+(unsigned int)itok.number); |
||
10603 | |||
10604 | else{ |
||
10605 | |||
10606 | op(0xC0+(unsigned int)itok.number+reg*8); |
||
10607 | |||
10608 | } |
||
10609 | |||
10610 | } |
||
10611 | |||
10612 | itok.number=vop/256; |
||
10613 | |||
10614 | break; |
||
10615 | |||
10616 | } |
||
10617 | |||
10618 | case tk_xorequals: vop+=0x08; |
||
10619 | |||
10620 | case tk_andequals: vop+=0x18; |
||
10621 | |||
10622 | case tk_plusequals: |
||
10623 | |||
10624 | inptr2--; |
||
10625 | |||
10626 | if(tok==tk_plusequals)tok=tk_plus; |
||
10627 | |||
10628 | doregmath64(reg); |
||
10629 | |||
10630 | break; |
||
10631 | |||
10632 | getoperand(reg1); |
||
10633 | |||
10634 | tok!=tk_postnumber)goto defadd; |
||
10635 | |||
10636 | idrec *rrec; |
||
10637 | |||
10638 | i=tok; |
||
10639 | |||
10640 | case tk_postnumber: |
||
10641 | |||
10642 | ii=itok.number; |
||
10643 | |||
10644 | opost=itok.post; |
||
10645 | |||
10646 | strcpy(uname,itok.name); |
||
10647 | |||
10648 | tok=tk_number; |
||
10649 | |||
10650 | ii=doconstqwordmath(); |
||
10651 | |||
10652 | if(itok.type==tp_opperand){ |
||
10653 | |||
10654 | if(i==tk_postnumber||i==tk_undefofs){ |
||
10655 | |||
10656 | op(0xB8+r1); // MOV reg,# |
||
10657 | |||
10658 | else{ |
||
10659 | |||
10660 | if(i==tk_undefofs)AddUndefOff(2,uname); |
||
10661 | |||
10662 | outdword(ii); |
||
10663 | |||
10664 | } |
||
10665 | |||
10666 | MovRegNum(r32,postnumflag&f_reloc,ii,reg1); |
||
10667 | |||
10668 | } |
||
10669 | |||
10670 | itok.number=sign; |
||
10671 | |||
10672 | } |
||
10673 | |||
10674 | optnumadd64(ii,r1,r2,vop); |
||
10675 | |||
10676 | } |
||
10677 | |||
10678 | op66(r32); |
||
10679 | |||
10680 | else{ |
||
10681 | |||
10682 | op(0xC0+vop+r1); |
||
10683 | |||
10684 | itok.rec=rrec; |
||
10685 | |||
10686 | if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii); |
||
10687 | |||
10688 | if((postnumflag&f_reloc)!=0)AddReloc(); |
||
10689 | |||
10690 | } |
||
10691 | |||
10692 | ii>>=32; |
||
10693 | |||
10694 | else if(vop==0x28)vop=0x18; |
||
10695 | |||
10696 | if(r2==AX)op(0x05+vop); |
||
10697 | |||
10698 | op(0x81); |
||
10699 | |||
10700 | } |
||
10701 | |||
10702 | break; |
||
10703 | |||
10704 | case tk_dwordvar: |
||
10705 | |||
10706 | op66(r32); |
||
10707 | |||
10708 | op(0x03+vop); |
||
10709 | |||
10710 | outaddress(&itok); |
||
10711 | |||
10712 | ZeroReg(r2,r32); |
||
10713 | |||
10714 | else{ |
||
10715 | |||
10716 | if(vop)vop=8; |
||
10717 | |||
10718 | op(0x83); |
||
10719 | |||
10720 | op(0); |
||
10721 | |||
10722 | } |
||
10723 | |||
10724 | case tk_qword: |
||
10725 | |||
10726 | reg=r1; |
||
10727 | |||
10728 | op66(r32); |
||
10729 | |||
10730 | op(0x03+vop); |
||
10731 | |||
10732 | outaddress(&itok); |
||
10733 | |||
10734 | reg=r2; |
||
10735 | |||
10736 | compressoffset(&itok); |
||
10737 | |||
10738 | break; |
||
10739 | |||
10740 | addreg: |
||
10741 | |||
10742 | reg2=itok.number&255; |
||
10743 | |||
10744 | op66(r32); |
||
10745 | |||
10746 | op(0xC0+reg+reg2*8); |
||
10747 | |||
10748 | if(vop==0)vop=0x10; |
||
10749 | |||
10750 | reg2=itok.number/256; |
||
10751 | |||
10752 | } |
||
10753 | |||
10754 | case tk_reg32: |
||
10755 | |||
10756 | op(0x01+vop); |
||
10757 | |||
10758 | if(vop==0x20){ //&= |
||
10759 | |||
10760 | } |
||
10761 | |||
10762 | if(vop==0||vop==0x28){ |
||
10763 | |||
10764 | op66(r32); |
||
10765 | |||
10766 | op(0xD0+vop+r2); |
||
10767 | |||
10768 | } |
||
10769 | |||
10770 | break; |
||
10771 | |||
10772 | case tk_id: |
||
10773 | |||
10774 | case tk_apiproc: |
||
10775 | |||
10776 | case tk_declare: |
||
10777 | |||
10778 | oaddstack=addstack; |
||
10779 | |||
10780 | op66(r32); |
||
10781 | |||
10782 | warningreg(regs[1][EAX]); |
||
10783 | |||
10784 | ClearReg(EAX); |
||
10785 | |||
10786 | } |
||
10787 | |||
10788 | op66(r32); |
||
10789 | |||
10790 | addESP+=4; |
||
10791 | |||
10792 | ClearReg(EDX); |
||
10793 | |||
10794 | } |
||
10795 | |||
10796 | addstack=oaddstack; |
||
10797 | |||
10798 | nexttok(); |
||
10799 | |||
10800 | next=0; |
||
10801 | |||
10802 | if(r1==EDX||r2==EDX){ |
||
10803 | |||
10804 | op(0x89); |
||
10805 | |||
10806 | op66(r32); |
||
10807 | |||
10808 | addESP-=4; |
||
10809 | |||
10810 | else reg2=EDX; |
||
10811 | |||
10812 | op66(r32); |
||
10813 | |||
10814 | op(0xC0+reg1+EAX*8); //mov reg,EAX |
||
10815 | |||
10816 | op(0x58); //pop ax |
||
10817 | |||
10818 | } |
||
10819 | |||
10820 | op66(r32); |
||
10821 | |||
10822 | op(0xc0+r1+reg1*8); //add reg,ax |
||
10823 | |||
10824 | if(vop==0x28)vop=0x18; |
||
10825 | |||
10826 | op(0x01+vop); |
||
10827 | |||
10828 | break; |
||
10829 | |||
10830 | case tk_charvar: |
||
10831 | |||
10832 | case tk_reg: |
||
10833 | |||
10834 | case tk_wordvar: |
||
10835 | |||
10836 | sign=reg1|(reg2*256); |
||
10837 | |||
10838 | |||
10839 | |||
10840 | warningreg(regs[1][reg2]); |
||
10841 | |||
10842 | ClearReg(reg2); |
||
10843 | |||
10844 | op(0x01+vop); |
||
10845 | |||
10846 | if(vop==0)vop=0x10; |
||
10847 | |||
10848 | op66(r32); |
||
10849 | |||
10850 | op(0xc0+r2+reg2*8); //add reg,ax |
||
10851 | |||
10852 | break; |
||
10853 | |||
10854 | } |
||
10855 | |||
10856 | case tk_rrequals: vop+=0x08; |
||
10857 | |||
10858 | getoperand(reg1); |
||
10859 | |||
10860 | if(tok==tk_number){ |
||
10861 | |||
10862 | next=0; |
||
10863 | |||
10864 | if(r1==ECX||r2==ECX)regshifterror(); |
||
10865 | |||
10866 | ConstToReg(ii,CL,r8); |
||
10867 | |||
10868 | warningreg(begs[1]); |
||
10869 | |||
10870 | goto shiftcl; |
||
10871 | |||
10872 | if(vop){ |
||
10873 | |||
10874 | r1=r2; |
||
10875 | |||
10876 | } |
||
10877 | |||
10878 | op66(r32); |
||
10879 | |||
10880 | op(0xA4+vop); |
||
10881 | |||
10882 | op(ii); |
||
10883 | |||
10884 | if(ii==1){ |
||
10885 | |||
10886 | } |
||
10887 | |||
10888 | op(0xC1); |
||
10889 | |||
10890 | op(ii); |
||
10891 | |||
10892 | } |
||
10893 | |||
10894 | op66(r32); |
||
10895 | |||
10896 | op(0xC0+r2+r1*8); |
||
10897 | |||
10898 | if(ii!=0){ |
||
10899 | |||
10900 | if(ii==1){ |
||
10901 | |||
10902 | op(0xE0+vop+r1); //shr ax,1 |
||
10903 | |||
10904 | else{ |
||
10905 | |||
10906 | op(0xE0+r2+vop); //shl ax,num |
||
10907 | |||
10908 | } |
||
10909 | |||
10910 | ZeroReg(r1,r32); |
||
10911 | |||
10912 | } |
||
10913 | |||
10914 | if(!(itok2.type==tp_stopper&&(tok==tk_beg||tok==reg||tok==tk_reg32)&&itok.number==CL)){ |
||
10915 | |||
10916 | dobegmath(CL); |
||
10917 | |||
10918 | ClearReg(CL); |
||
10919 | |||
10920 | } |
||
10921 | |||
10922 | op66(r32); |
||
10923 | |||
10924 | op(0xA5+vop); |
||
10925 | |||
10926 | reg=r1; |
||
10927 | |||
10928 | r2=reg; |
||
10929 | |||
10930 | op(0xC0+r2+r1*8); |
||
10931 | |||
10932 | op(0xD3); |
||
10933 | |||
10934 | } |
||
10935 | |||
10936 | break; |
||
10937 | |||
10938 | getoperand(reg1); |
||
10939 | |||
10940 | if(tok==tk_number){ |
||
10941 | |||
10942 | next=0; |
||
10943 | |||
10944 | op66(r32); |
||
10945 | |||
10946 | op66(r32); |
||
10947 | |||
10948 | addESP+=8; |
||
10949 | |||
10950 | MovRegNum(r32,0,ii>>32,reg2); |
||
10951 | |||
10952 | ConstToReg(ii>>32,reg2,r32); |
||
10953 | |||
10954 | goto mul; |
||
10955 | |||
10956 | i=0; |
||
10957 | |||
10958 | if(ii==0){ |
||
10959 | |||
10960 | ZeroReg(r2,r32); |
||
10961 | |||
10962 | } |
||
10963 | |||
10964 | if(ii==2){ |
||
10965 | |||
10966 | op(1); |
||
10967 | |||
10968 | op66(r32); |
||
10969 | |||
10970 | op(0xC2+r2*8); //adc r2,0 |
||
10971 | |||
10972 | break; |
||
10973 | |||
10974 | if((i=caselonglong(ii))!=NUMNUM64){ |
||
10975 | |||
10976 | op66(r32); |
||
10977 | |||
10978 | op(0xC0+r2+r1*8); |
||
10979 | |||
10980 | op66(r32); |
||
10981 | |||
10982 | op(0xE0+r1); //shl ax,num |
||
10983 | |||
10984 | } |
||
10985 | |||
10986 | op66(r32); |
||
10987 | |||
10988 | op(0xC0+r2+r1*8); |
||
10989 | |||
10990 | if(i!=0){ |
||
10991 | |||
10992 | if(i==1){ |
||
10993 | |||
10994 | op(0xC0+r2*9); //add reg,reg |
||
10995 | |||
10996 | else{ |
||
10997 | |||
10998 | op(0xE0+r2); //shl ax,num |
||
10999 | |||
11000 | } |
||
11001 | |||
11002 | ZeroReg(r1,r32); |
||
11003 | |||
11004 | break; |
||
11005 | |||
11006 | } |
||
11007 | |||
11008 | op(0x50+r2); |
||
11009 | |||
11010 | op(0x50+r1); |
||
11011 | |||
11012 | MovRegNum(r32,postnumflag&f_reloc,ii,ECX); |
||
11013 | |||
11014 | goto mul; |
||
11015 | |||
11016 | op66(r32); |
||
11017 | |||
11018 | op66(r32); |
||
11019 | |||
11020 | addESP+=8; |
||
11021 | |||
11022 | warningreg(regs[1][ECX]); |
||
11023 | |||
11024 | doregmath64(reg); |
||
11025 | |||
11026 | CallExternProc("__llmul"); |
||
11027 | |||
11028 | endmul: |
||
11029 | |||
11030 | warningreg(regs[1][EAX]); |
||
11031 | |||
11032 | warningreg(regs[1][EDX]); |
||
11033 | |||
11034 | if(r1!=EAX){ |
||
11035 | |||
11036 | if(r2==EAX){ |
||
11037 | |||
11038 | op(0x90+EDX); |
||
11039 | |||
11040 | } |
||
11041 | |||
11042 | op(0x89); |
||
11043 | |||
11044 | op66(r32); |
||
11045 | |||
11046 | op(0xC0+r1+EAX*8); //mov reg,EAX |
||
11047 | |||
11048 | } |
||
11049 | |||
11050 | op(0x89); |
||
11051 | |||
11052 | } |
||
11053 | |||
11054 | op66(r32); |
||
11055 | |||
11056 | op(0xC0+r2+EDX*8); //mov reg,EDX |
||
11057 | |||
11058 | break; |
||
11059 | |||
11060 | getoperand(reg1); |
||
11061 | |||
11062 | if(tok==tk_number){ |
||
11063 | |||
11064 | next=0; |
||
11065 | |||
11066 | MovRegNum(r32,postnumflag&f_reloc,ii,reg1); |
||
11067 | |||
11068 | ConstToReg(ii,reg1,r32); |
||
11069 | |||
11070 | doregmath64(reg1|(reg2*256)); |
||
11071 | |||
11072 | op(0x50+reg2); |
||
11073 | |||
11074 | op(0x50+reg1); |
||
11075 | |||
11076 | warningreg(regs[1][reg1]); |
||
11077 | |||
11078 | goto divcont; |
||
11079 | |||
11080 | if((postnumflag&f_reloc)==0){ |
||
11081 | |||
11082 | DevideZero(); |
||
11083 | |||
11084 | } |
||
11085 | |||
11086 | if((i=caselonglong(ii))!=NUMNUM64){ |
||
11087 | |||
11088 | op66(r32); |
||
11089 | |||
11090 | op(0xC0+r1+r2*8); |
||
11091 | |||
11092 | op66(r32); |
||
11093 | |||
11094 | op(0xe8+r2); // SHR reg,imm8 |
||
11095 | |||
11096 | } |
||
11097 | |||
11098 | op66(r32); |
||
11099 | |||
11100 | op(0xC0+r1+r2*8); |
||
11101 | |||
11102 | if(i!=0){ |
||
11103 | |||
11104 | if(i==1){ |
||
11105 | |||
11106 | |||
11107 | |||
11108 | else{ |
||
11109 | |||
11110 | op(0xE8+r1); //shr ax,num |
||
11111 | |||
11112 | } |
||
11113 | |||
11114 | ZeroReg(r2,r32); |
||
11115 | |||
11116 | break; |
||
11117 | |||
11118 | } |
||
11119 | |||
11120 | number=ii>>32; |
||
11121 | |||
11122 | op66(r32); |
||
11123 | |||
11124 | op(0x6A); |
||
11125 | |||
11126 | } |
||
11127 | |||
11128 | op(0x68); |
||
11129 | |||
11130 | outdword(number); |
||
11131 | |||
11132 | if(i==1)break; |
||
11133 | |||
11134 | } |
||
11135 | |||
11136 | goto divcont; |
||
11137 | |||
11138 | reg=reg1|(reg2*256); |
||
11139 | |||
11140 | doregmath64(reg); |
||
11141 | |||
11142 | op(0x50+reg2); |
||
11143 | |||
11144 | op(0x50+reg1); |
||
11145 | |||
11146 | warningreg(regs[1][reg1]); |
||
11147 | |||
11148 | next=0; |
||
11149 | |||
11150 | if(r1!=EAX){ |
||
11151 | |||
11152 | if(r1==EDX){ |
||
11153 | |||
11154 | op(0x90+EDX); |
||
11155 | |||
11156 | } |
||
11157 | |||
11158 | op(0x89); |
||
11159 | |||
11160 | op66(r32); |
||
11161 | |||
11162 | op(0xC0+EAX+r1*8); //mov EAX,r1 |
||
11163 | |||
11164 | } |
||
11165 | |||
11166 | op(0x89); |
||
11167 | |||
11168 | } |
||
11169 | |||
11170 | op66(r32); |
||
11171 | |||
11172 | op(0xC0+EDX+r2*8); //mov EDX,r2 |
||
11173 | |||
11174 | sdiv: |
||
11175 | |||
11176 | addESP-=8; |
||
11177 | |||
11178 | default: operatorexpected(); break; |
||
11179 | |||
11180 | ClearReg(r1); |
||
11181 | |||
11182 | if(next)nexttok(); |
||
11183 | |||
11184 | if(cpu<3)cpu=3; |
||
11185 | |||
11186 | |||
11187 | |||
11188 | { |
||
11189 | |||
11190 | if(num==0){ |
||
11191 | |||
11192 | reg=r1; |
||
11193 | |||
11194 | ZeroReg(reg,r32); |
||
11195 | |||
11196 | } |
||
11197 | |||
11198 | } |
||
11199 | |||
11200 | } |
||
11201 | |||
11202 | if(vop==0x28){ //-= |
||
11203 | |||
11204 | op(0x48+r1); |
||
11205 | |||
11206 | op(0x83); |
||
11207 | |||
11208 | op(0); |
||
11209 | |||
11210 | return; |
||
11211 | |||
11212 | if(vop==0){ //+= |
||
11213 | |||
11214 | op(0x40+r1); |
||
11215 | |||
11216 | op(0x83); |
||
11217 | |||
11218 | op(0); |
||
11219 | |||
11220 | return; |
||
11221 | |||
11222 | } |
||
11223 | |||
11224 | if(num<65536){ |
||
11225 | |||
11226 | if(r1==AX)op(0x0C); |
||
11227 | |||
11228 | op(0x80); |
||
11229 | |||
11230 | } |
||
11231 | |||
11232 | return; |
||
11233 | |||
11234 | op66(r16); |
||
11235 | |||
11236 | else{ |
||
11237 | |||
11238 | op(0xc8+r1); |
||
11239 | |||
11240 | outword(num); |
||
11241 | |||
11242 | } |
||
11243 | |||
11244 | op66(r32); |
||
11245 | |||
11246 | else{ |
||
11247 | |||
11248 | op(0xc8+r1); |
||
11249 | |||
11250 | outdword(num); |
||
11251 | |||
11252 | } |
||
11253 | |||
11254 | if(vop==0x20){ //&= |
||
11255 | |||
11256 | if((unsigned long)num>=0xFFFF0000){ |
||
11257 | |||
11258 | if(r1==AL)op(0x24); |
||
11259 | |||
11260 | op(128); |
||
11261 | |||
11262 | } |
||
11263 | |||
11264 | return; |
||
11265 | |||
11266 | op66(r16); |
||
11267 | |||
11268 | else{ |
||
11269 | |||
11270 | op(0xE0+r1); |
||
11271 | |||
11272 | outword(num); |
||
11273 | |||
11274 | } |
||
11275 | |||
11276 | if(r1==AX)op(0x25); |
||
11277 | |||
11278 | op(129); |
||
11279 | |||
11280 | } |
||
11281 | |||
11282 | return; |
||
11283 | |||
11284 | } |
||
11285 | |||
11286 | int j=0; |
||
11287 | |||
11288 | if((unsigned long)num==0)j++; |
||
11289 | |||
11290 | op66(r32); |
||
11291 | |||
11292 | op(0x83); |
||
11293 | |||
11294 | op(num); |
||
11295 | |||
11296 | else{ |
||
11297 | |||
11298 | else{ |
||
11299 | |||
11300 | op(0xC0+vop+reg); |
||
11301 | |||
11302 | outdword(num); |
||
11303 | |||
11304 | } |
||
11305 | |||
11306 | if(j==0&&(vop==0||vop==0x28)){ |
||
11307 | |||
11308 | op66(r32); |
||
11309 | |||
11310 | op(0x83); |
||
11311 | |||
11312 | op(num); |
||
11313 | |||
11314 | else{ |
||
11315 | |||
11316 | else{ |
||
11317 | |||
11318 | op(0xD3+vop+r2); |
||
11319 | |||
11320 | outdword(num); |
||
11321 | |||
11322 | break; |
||
11323 | |||
11324 | reg=r2; |
||
11325 | |||
11326 | setzeroflag=TRUE; |
||
11327 | |||
11328 | |||
11329 | |||
11330 | { |
||
11331 | |||
11332 | int r1,r2,next=1; |
||
11333 | |||
11334 | char *ofsstr=NULL; |
||
11335 | |||
11336 | r2=reg/256; |
||
11337 | |||
11338 | while(itok.type!=tp_stopper&&tok!=tk_eof){ |
||
11339 | |||
11340 | op66(r32); |
||
11341 | |||
11342 | op(0xD8+r2); // NEG reg |
||
11343 | |||
11344 | op(0xF7); |
||
11345 | |||
11346 | op66(r32); |
||
11347 | |||
11348 | op(0xD8+r2); |
||
11349 | |||
11350 | ClearReg(r1); |
||
11351 | |||
11352 | negflag=FALSE; |
||
11353 | |||
11354 | vop=0; |
||
11355 | |||
11356 | optnum=FALSE; |
||
11357 | |||
11358 | switch(tok){ |
||
11359 | |||
11360 | case tk_minus: vop+=0x08; |
||
11361 | |||
11362 | case tk_or: vop+=0x08; |
||
11363 | |||
11364 | if(optnum==FALSE)getoperand(reg1); |
||
11365 | |||
11366 | switch(tok){ |
||
11367 | |||
11368 | if((itok.flag&f_reloc)==0){ |
||
11369 | |||
11370 | break; |
||
11371 | |||
11372 | case tk_postnumber: |
||
11373 | |||
11374 | case tk_apioffset: |
||
11375 | |||
11376 | op(0x81); |
||
11377 | |||
11378 | if(tok==tk_apioffset)AddApiToPost(itok.number); |
||
11379 | |||
11380 | if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
11381 | |||
11382 | else if((itok.flag&f_reloc)!=0)AddReloc(); |
||
11383 | |||
11384 | } |
||
11385 | |||
11386 | ZeroReg(r2,r32); |
||
11387 | |||
11388 | else{ |
||
11389 | |||
11390 | if(vop)vop=8; |
||
11391 | |||
11392 | op(0x83); |
||
11393 | |||
11394 | op(0); |
||
11395 | |||
11396 | } |
||
11397 | |||
11398 | case tk_rmnumber: |
||
11399 | |||
11400 | case tk_beg: |
||
11401 | |||
11402 | getintoreg_32(reg2,r32,0,&ofsstr,FALSE); |
||
11403 | |||
11404 | op(0x01+vop); |
||
11405 | |||
11406 | if(vop==0x20){ //&= |
||
11407 | |||
11408 | } |
||
11409 | |||
11410 | if(vop==0||vop==0x28){ |
||
11411 | |||
11412 | op66(r32); |
||
11413 | |||
11414 | op(0xD0+vop+r2); |
||
11415 | |||
11416 | } |
||
11417 | |||
11418 | warningreg(regs[r32/2-1][reg2]); |
||
11419 | |||
11420 | break; |
||
11421 | |||
11422 | op66(r32); |
||
11423 | |||
11424 | if(itok.number==r1||itok.number==r2)itok.number=reg1; |
||
11425 | |||
11426 | warningreg(regs[1][itok.number]); |
||
11427 | |||
11428 | defreg32: |
||
11429 | |||
11430 | op(0x01+vop); |
||
11431 | |||
11432 | if(vop==0x20){ //&= |
||
11433 | |||
11434 | } |
||
11435 | |||
11436 | if(vop==0||vop==0x28){ |
||
11437 | |||
11438 | op66(r32); |
||
11439 | |||
11440 | op(0xD0+vop+r2); |
||
11441 | |||
11442 | } |
||
11443 | |||
11444 | break; |
||
11445 | |||
11446 | int reg2; |
||
11447 | |||
11448 | reg2=itok.number&255; |
||
11449 | |||
11450 | op66(r32); |
||
11451 | |||
11452 | op(0xC0+reg+reg2*8); |
||
11453 | |||
11454 | if(vop==0)vop=0x10; |
||
11455 | |||
11456 | reg2=itok.number/256; |
||
11457 | |||
11458 | } |
||
11459 | |||
11460 | case tk_longvar: |
||
11461 | |||
11462 | CheckAllMassiv(bufrm,4,&strinf); |
||
11463 | |||
11464 | outseg(&itok,2); |
||
11465 | |||
11466 | op(r1*8+itok.rm); |
||
11467 | |||
11468 | if(vop==0x20){ //&= |
||
11469 | |||
11470 | } |
||
11471 | |||
11472 | if(vop==0||vop==0x28){ |
||
11473 | |||
11474 | op66(r32); |
||
11475 | |||
11476 | op(0xD0+vop+r2); |
||
11477 | |||
11478 | } |
||
11479 | |||
11480 | break; |
||
11481 | |||
11482 | reg=r1; |
||
11483 | |||
11484 | CheckAllMassiv(bufrm,8,&strinf); |
||
11485 | |||
11486 | outseg(&itok,2); |
||
11487 | |||
11488 | op(reg*8+itok.rm); |
||
11489 | |||
11490 | if(i==1)break; |
||
11491 | |||
11492 | if(vop==0x28)vop=0x18; |
||
11493 | |||
11494 | compressoffset(&itok); |
||
11495 | |||
11496 | } |
||
11497 | |||
11498 | case tk_ID: |
||
11499 | |||
11500 | case tk_proc: |
||
11501 | |||
11502 | case tk_undefproc: |
||
11503 | |||
11504 | procdo(tk_qword); |
||
11505 | |||
11506 | op(0x01+vop); |
||
11507 | |||
11508 | warningreg(regs[1][0]); |
||
11509 | |||
11510 | if(vop==0x28)vop=0x18; |
||
11511 | |||
11512 | op(0x01+vop); |
||
11513 | |||
11514 | warningreg(regs[1][EDX]); |
||
11515 | |||
11516 | default: valueexpected(); break; |
||
11517 | |||
11518 | break; |
||
11519 | |||
11520 | if(r1==ECX||r2==ECX){ |
||
11521 | |||
11522 | break; |
||
11523 | |||
11524 | tok=tk_minus; |
||
11525 | |||
11526 | case tk_rr: |
||
11527 | |||
11528 | if(tok==tk_number){ |
||
11529 | |||
11530 | outword(0xAC0F); |
||
11531 | |||
11532 | op(itok.number); |
||
11533 | |||
11534 | if((unsigned int)itok.number==1){ |
||
11535 | |||
11536 | } |
||
11537 | |||
11538 | op(0xc1); |
||
11539 | |||
11540 | op((unsigned int)itok.number); |
||
11541 | |||
11542 | } |
||
11543 | |||
11544 | else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==CL)goto rshift; |
||
11545 | |||
11546 | rshift2: |
||
11547 | |||
11548 | next=0; |
||
11549 | |||
11550 | rshift: |
||
11551 | |||
11552 | outword(0xAD0F); |
||
11553 | |||
11554 | op66(r32); |
||
11555 | |||
11556 | op(0xE8+r2); // SHL xXX,CL |
||
11557 | |||
11558 | break; |
||
11559 | |||
11560 | if(r1==ECX||r2==ECX){ |
||
11561 | |||
11562 | break; |
||
11563 | |||
11564 | tok=tk_minus; |
||
11565 | |||
11566 | case tk_ll: |
||
11567 | |||
11568 | if(tok==tk_number){ |
||
11569 | |||
11570 | outword(0xA40F); |
||
11571 | |||
11572 | op(itok.number); |
||
11573 | |||
11574 | if((unsigned int)itok.number==1){ |
||
11575 | |||
11576 | op(0xC0+r1*9); //add reg,reg |
||
11577 | |||
11578 | else{ |
||
11579 | |||
11580 | op(0xE0+r1); //shl ax,num |
||
11581 | |||
11582 | } |
||
11583 | |||
11584 | else if(r1==ECX||r2==ECX)regshifterror(); |
||
11585 | |||
11586 | else{ |
||
11587 | |||
11588 | getintobeg(CL,&ofsstr); |
||
11589 | |||
11590 | warningreg(begs[1]); |
||
11591 | |||
11592 | op66(r32); |
||
11593 | |||
11594 | op(0xC0+r2+r1*8); |
||
11595 | |||
11596 | op(0xD3); |
||
11597 | |||
11598 | } |
||
11599 | |||
11600 | case tk_multminus: negflag=TRUE; |
||
11601 | |||
11602 | getoperand(reg1); |
||
11603 | |||
11604 | itok.lnumber=-itok.lnumber; |
||
11605 | |||
11606 | } |
||
11607 | |||
11608 | if(itok.lnumber==0){ |
||
11609 | |||
11610 | ZeroReg(r2,r32); |
||
11611 | |||
11612 | } |
||
11613 | |||
11614 | if(itok.lnumber==2){ |
||
11615 | |||
11616 | op(1); |
||
11617 | |||
11618 | op66(r32); |
||
11619 | |||
11620 | op(0xC2+r2*8); //adc r2,0 |
||
11621 | |||
11622 | break; |
||
11623 | |||
11624 | if((i=caselonglong(itok.lnumber))!=NUMNUM64){ |
||
11625 | |||
11626 | op66(r32); |
||
11627 | |||
11628 | op(0xC0+r2+r1*8); |
||
11629 | |||
11630 | op66(r32); |
||
11631 | |||
11632 | op(0xE0+r1); //shl ax,num |
||
11633 | |||
11634 | } |
||
11635 | |||
11636 | |||
11637 | |||
11638 | op(0xC0+r2+r1*8); |
||
11639 | |||
11640 | if(i!=0){ |
||
11641 | |||
11642 | if(i==1){ |
||
11643 | |||
11644 | op(0xC0+r2*9); //add reg,reg |
||
11645 | |||
11646 | else{ |
||
11647 | |||
11648 | op(0xE0+r2); //shl ax,num |
||
11649 | |||
11650 | } |
||
11651 | |||
11652 | ZeroReg(r1,r32); |
||
11653 | |||
11654 | break; |
||
11655 | |||
11656 | op66(r32); |
||
11657 | |||
11658 | op66(r32); |
||
11659 | |||
11660 | addESP+=8; |
||
11661 | |||
11662 | MovRegNum(r32,0,itok.lnumber>>32,EAX); |
||
11663 | |||
11664 | } |
||
11665 | |||
11666 | op66(r32); |
||
11667 | |||
11668 | op66(r32); |
||
11669 | |||
11670 | addESP+=8; |
||
11671 | |||
11672 | getintoreg64(reg); |
||
11673 | |||
11674 | next=0; |
||
11675 | |||
11676 | CallExternProc("__llmul"); |
||
11677 | |||
11678 | endmul: |
||
11679 | |||
11680 | if(r1==EDX){ |
||
11681 | |||
11682 | op66(r32); |
||
11683 | |||
11684 | break; |
||
11685 | |||
11686 | op66(r32); |
||
11687 | |||
11688 | op(0xC0+r2+EDX*8); //mov reg,EDX |
||
11689 | |||
11690 | op(0x89); |
||
11691 | |||
11692 | break; |
||
11693 | |||
11694 | op66(r32); |
||
11695 | |||
11696 | op(0xC0+r1+EAX*8); //mov reg,EAX |
||
11697 | |||
11698 | if(r2!=EDX){ |
||
11699 | |||
11700 | op(0x89); |
||
11701 | |||
11702 | } |
||
11703 | |||
11704 | case tk_modminus: negflag=TRUE; |
||
11705 | |||
11706 | vop=1; |
||
11707 | |||
11708 | case tk_divminus: negflag=TRUE; |
||
11709 | |||
11710 | divcalc: |
||
11711 | |||
11712 | if(negflag&&tok==tk_number){ |
||
11713 | |||
11714 | negflag=FALSE; |
||
11715 | |||
11716 | if(tok==tk_number&&((itok.flag&f_reloc)==0)){ |
||
11717 | |||
11718 | DevideZero(); |
||
11719 | |||
11720 | } |
||
11721 | |||
11722 | if(vop){ //mod |
||
11723 | |||
11724 | ZeroReg(r2,r32); |
||
11725 | |||
11726 | break; |
||
11727 | |||
11728 | if((i=caselonglong(itok.lnumber))!=NUMNUM64){ |
||
11729 | |||
11730 | optnumadd64(itok.lnumber-1,r1,r2,0x20); |
||
11731 | |||
11732 | else{ |
||
11733 | |||
11734 | op66(r32); |
||
11735 | |||
11736 | op(0xC0+r1+r2*8); |
||
11737 | |||
11738 | op66(r32); |
||
11739 | |||
11740 | op(0xe8+r2); // SHR reg,imm8 |
||
11741 | |||
11742 | } |
||
11743 | |||
11744 | op66(r32); |
||
11745 | |||
11746 | op(0xC0+r1+r2*8); |
||
11747 | |||
11748 | if(i!=0){ |
||
11749 | |||
11750 | if(i==1){ |
||
11751 | |||
11752 | op(0xE8+r1); //shr ax,1 |
||
11753 | |||
11754 | else{ |
||
11755 | |||
11756 | op(0xE8+r1); //shr ax,num |
||
11757 | |||
11758 | } |
||
11759 | |||
11760 | ZeroReg(r2,r32); |
||
11761 | |||
11762 | } |
||
11763 | |||
11764 | } |
||
11765 | |||
11766 | number=itok.lnumber>>32; |
||
11767 | |||
11768 | op66(r32); |
||
11769 | |||
11770 | op(0x6A); |
||
11771 | |||
11772 | } |
||
11773 | |||
11774 | op(0x68); |
||
11775 | |||
11776 | outdword(number); |
||
11777 | |||
11778 | if(i==1)break; |
||
11779 | |||
11780 | } |
||
11781 | |||
11782 | goto divcont; |
||
11783 | |||
11784 | reg=reg1|(reg2*256); |
||
11785 | |||
11786 | op66(r32); |
||
11787 | |||
11788 | op66(r32); |
||
11789 | |||
11790 | addESP+=8; |
||
11791 | |||
11792 | divcont: |
||
11793 | |||
11794 | if(r2==EAX){ |
||
11795 | |||
11796 | op66(r32); |
||
11797 | |||
11798 | goto sdiv; |
||
11799 | |||
11800 | op66(r32); |
||
11801 | |||
11802 | op(0xC0+EDX+r2*8); //mov EDX,r2 |
||
11803 | |||
11804 | op(0x89); |
||
11805 | |||
11806 | goto sdiv; |
||
11807 | |||
11808 | op66(r32); |
||
11809 | |||
11810 | op(0xC0+EAX+r1*8); //mov EAX,r1 |
||
11811 | |||
11812 | if(r2!=EDX){ |
||
11813 | |||
11814 | op(0x89); |
||
11815 | |||
11816 | } |
||
11817 | |||
11818 | CallExternProc((char*)(vop==0?"__lludiv":"__llumod")); |
||
11819 | |||
11820 | goto endmul; |
||
11821 | |||
11822 | } |
||
11823 | |||
11824 | } |
||
11825 | |||
11826 | ClearReg(r2); |
||
11827 | |||
11828 | } |
||
11829 | |||
11830 | void getintoreg64(int reg) |
||
11831 | |||
11832 | int negflag=0,next=1,i=0; |
||
11833 | |||
11834 | int r1,r2; |
||
11835 | |||
11836 | r1=reg&255; |
||
11837 | |||
11838 | Select2FreeReg(r1,r2,®1,®2); |
||
11839 | |||
11840 | if(CheckMinusNum()==FALSE){ |
||
11841 | |||
11842 | getoperand(am32==FALSE?BX:r1); |
||
11843 | |||
11844 | } |
||
11845 | |||
11846 | case tk_number: |
||
11847 | |||
11848 | MovRegNum(r32,postnumflag&f_reloc,holdnumber,r1); |
||
11849 | |||
11850 | next=0; |
||
11851 | |||
11852 | case tk_postnumber: |
||
11853 | |||
11854 | case tk_apioffset: |
||
11855 | |||
11856 | op(0xB8+r1); /* MOV AX,# */ |
||
11857 | |||
11858 | else{ |
||
11859 | |||
11860 | else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
||
11861 | |||
11862 | holdnumber+=doconstdwordmath(); |
||
11863 | |||
11864 | MovRegNum(r32,0,holdnumber>>32,r2); |
||
11865 | |||
11866 | } |
||
11867 | |||
11868 | |||
11869 | |||
11870 | case tk_rmnumber: |
||
11871 | |||
11872 | if(!(am32&&itok.rm==r1&&r1!=EBP&&r1!=ESP)){ |
||
11873 | |||
11874 | op67(itok.sib==CODE16?r16:r32); |
||
11875 | |||
11876 | op(0x8D); // LEA reg,[rm] |
||
11877 | |||
11878 | if(itok.post!=0&&itok.post!=UNDEF_OFSET){ |
||
11879 | |||
11880 | unsigned int ooutptr=outptr; |
||
11881 | |||
11882 | setwordpost(&itok); |
||
11883 | |||
11884 | } |
||
11885 | |||
11886 | } |
||
11887 | |||
11888 | ClearReg(r1); |
||
11889 | |||
11890 | ZeroReg(r2,r32); |
||
11891 | |||
11892 | |||
11893 | |||
11894 | for(i=0;i<2;i++){ |
||
11895 | |||
11896 | op66(r32); |
||
11897 | |||
11898 | op(0xA1); |
||
11899 | |||
11900 | if(am32==FALSE)outword((unsigned int)itok.number); |
||
11901 | |||
11902 | } |
||
11903 | |||
11904 | CheckAllMassiv(bufrm,8,&strinf,&itok,reg1,reg2); |
||
11905 | |||
11906 | outseg(&itok,2); |
||
11907 | |||
11908 | op(reg*8+itok.rm); |
||
11909 | |||
11910 | } |
||
11911 | |||
11912 | if(i==1)break; |
||
11913 | |||
11914 | |||
11915 | |||
11916 | } |
||
11917 | |||
11918 | |||
11919 | |||
11920 | if(reg==EAX&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){ |
||
11921 | |||
11922 | outseg(&itok,1); |
||
11923 | |||
11924 | if(itok.post==UNDEF_OFSET)AddUndefOff(2,itok.name); |
||
11925 | |||
11926 | else outdword(itok.number); |
||
11927 | |||
11928 | else{ |
||
11929 | |||
11930 | op66(r32); |
||
11931 | |||
11932 | op(0x8B); |
||
11933 | |||
11934 | outaddress(&itok); |
||
11935 | |||
11936 | ZeroReg(r2,r32); |
||
11937 | |||
11938 | break; |
||
11939 | |||
11940 | case tk_wordvar: |
||
11941 | |||
11942 | if(tok==tk_wordvar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ |
||
11943 | |||
11944 | op66(r16); |
||
11945 | |||
11946 | op(0x8B); |
||
11947 | |||
11948 | else{ |
||
11949 | |||
11950 | outseg(&itok,3); //movxx reg,var |
||
11951 | |||
11952 | } |
||
11953 | |||
11954 | outaddress(&itok); |
||
11955 | |||
11956 | ZeroReg(r2,r32); |
||
11957 | |||
11958 | case tk_bytevar: |
||
11959 | |||
11960 | CheckAllMassiv(bufrm,1,&strinf,&itok,reg1,reg2); |
||
11961 | |||
11962 | ZeroReg(r1,r32); |
||
11963 | |||
11964 | op(0x8A); |
||
11965 | |||
11966 | else{ |
||
11967 | |||
11968 | outseg(&itok,3); |
||
11969 | |||
11970 | if(tok==tk_bytevar)op(0xb6); |
||
11971 | |||
11972 | } |
||
11973 | |||
11974 | outaddress(&itok); |
||
11975 | |||
11976 | ZeroReg(r2,r32); |
||
11977 | |||
11978 | case tk_reg: |
||
11979 | |||
11980 | reg1=itok.number; |
||
11981 | |||
11982 | param[0]=0; |
||
11983 | |||
11984 | else doparams(); |
||
11985 | |||
11986 | op(0xFF); |
||
11987 | |||
11988 | itok.number=0; |
||
11989 | |||
11990 | #ifdef OPTVARCONST |
||
11991 | |||
11992 | #endif |
||
11993 | |||
11994 | if(optimizespeed&&chip>3&&chip<7&®!=(int)itok.number){ |
||
11995 | |||
11996 | op(0x89); |
||
11997 | |||
11998 | } |
||
11999 | |||
12000 | op66(r32); |
||
12001 | |||
12002 | op(0xC0+r1*8+(unsigned int)itok.number); |
||
12003 | |||
12004 | RegToReg(r1,itok.number,r32); |
||
12005 | |||
12006 | break; |
||
12007 | |||
12008 | if(tok2==tk_openbracket){ //вызов процедуры по адресу в регистре |
||
12009 | |||
12010 | nexttok(); |
||
12011 | |||
12012 | if(comfile==file_w32)swapparam(); |
||
12013 | |||
12014 | op66(r32); |
||
12015 | |||
12016 | op(0xD0+reg1); /* CALL reg with stack params */ |
||
12017 | |||
12018 | clearregstat(); |
||
12019 | |||
12020 | FreeGlobalConst(); |
||
12021 | |||
12022 | } |
||
12023 | |||
12024 | op66(r32); |
||
12025 | |||
12026 | op(0xC0+r1+(unsigned int)itok.number*8); |
||
12027 | |||
12028 | } |
||
12029 | |||
12030 | break; |
||
12031 | |||
12032 | reg1=itok.number&255; |
||
12033 | |||
12034 | movreg64: |
||
12035 | |||
12036 | if(r2==reg1){ |
||
12037 | |||
12038 | if(r1==AX)op(0x90+r2); |
||
12039 | |||
12040 | else{ |
||
12041 | |||
12042 | op(0xC0+r1+r2*8); |
||
12043 | |||
12044 | break; |
||
12045 | |||
12046 | int temp; |
||
12047 | |||
12048 | r2=r1; |
||
12049 | |||
12050 | temp=reg2; |
||
12051 | |||
12052 | reg1=temp; |
||
12053 | |||
12054 | if(r2==reg1){ |
||
12055 | |||
12056 | temp=r2; |
||
12057 | |||
12058 | r1=temp; |
||
12059 | |||
12060 | reg2=reg1; |
||
12061 | |||
12062 | } |
||
12063 | |||
12064 | op66(r32); |
||
12065 | |||
12066 | op(0xC0+r1+reg1*8); |
||
12067 | |||
12068 | } |
||
12069 | |||
12070 | op66(r32); |
||
12071 | |||
12072 | op(0xC0+r2+reg2*8); |
||
12073 | |||
12074 | } |
||
12075 | |||
12076 | case tk_bits: |
||
12077 | |||
12078 | i=itok.bit.siz+itok.bit.ofs; |
||
12079 | |||
12080 | if(i<=32)vops=r32; |
||
12081 | |||
12082 | bits2reg(r1,(r32 |
||
12083 | |||
12084 | break; |
||
12085 | |||
12086 | op66(r32); |
||
12087 | |||
12088 | op(0xC0+r1+(unsigned int)itok.number*8); |
||
12089 | |||
12090 | ZeroReg(r2,r32); |
||
12091 | |||
12092 | case tk_beg: |
||
12093 | |||
12094 | ZeroReg(r1,r32); |
||
12095 | |||
12096 | op(0xC0+r1+(unsigned int)itok.number*8); // MOV regL,beg |
||
12097 | |||
12098 | else{ |
||
12099 | |||
12100 | outword(0xb60f); |
||
12101 | |||
12102 | } |
||
12103 | |||
12104 | ZeroReg(r2,r32); |
||
12105 | |||
12106 | case tk_at: |
||
12107 | |||
12108 | i++; |
||
12109 | |||
12110 | case tk_id: |
||
12111 | |||
12112 | case tk_apiproc: |
||
12113 | |||
12114 | case tk_declare: |
||
12115 | |||
12116 | reg1=EAX; reg2=EDX; |
||
12117 | |||
12118 | case tk_string: |
||
12119 | |||
12120 | op(0xB8+r1); |
||
12121 | |||
12122 | ClearReg(r1); |
||
12123 | |||
12124 | break; |
||
12125 | |||
12126 | } |
||
12127 | |||
12128 | op66(r32); |
||
12129 | |||
12130 | op(0xD8+r2); // NEG reg |
||
12131 | |||
12132 | op(0xF7); |
||
12133 | |||
12134 | op66(r32); |
||
12135 | |||
12136 | op(0xD8+r2); |
||
12137 | |||
12138 | ClearReg(r1); |
||
12139 | |||
12140 | } |
||
12141 | |||
12142 | } |
||
12143 | |||
12144 | void CallExternProc(char *name) |
||
12145 | |||
12146 | ITOK itok4; |
||
12147 | |||
12148 | char string4[256]; |
||
12149 | |||
12150 | memset(&itok4,0,sizeof(ITOK)); |
||
12151 | |||
12152 | searchtree(&itok4,&tok4,(unsigned char *)string4); |
||
12153 | |||
12154 | switch(tok4){ |
||
12155 | |||
12156 | tok4=tok; |
||
12157 | |||
12158 | strcpy((char *)itok.name,string4); |
||
12159 | |||
12160 | itok.flag=tp_stdcall; |
||
12161 | |||
12162 | itok.number=secondcallnum; |
||
12163 | |||
12164 | itok.rm=tk_qword; |
||
12165 | |||
12166 | addtotree(itok.name); |
||
12167 | |||
12168 | tok=tok4; |
||
12169 | |||
12170 | callloc0(); |
||
12171 | |||
12172 | case tk_declare: |
||
12173 | |||
12174 | case tk_undefproc: |
||
12175 | |||
12176 | callloc0(); /* produce CALL [#] */ |
||
12177 | |||
12178 | case tk_proc: |
||
12179 | |||
12180 | if(itok4.segm |
||
12181 | |||
12182 | callloc0(); |
||
12183 | |||
12184 | else{ |
||
12185 | |||
12186 | } |
||
12187 | |||
12188 | default: |
||
12189 | |||
12190 | preerror(string4); |
||
12191 | |||
12192 | } |
||
12193 | |||
12194 | /* end of TOKB.C */4&®!=(int)(itok.number%4)){ |
||
12195 | |||
12196 | > |
||
12197 | |||
12198 | >=32)vops=r32; |
||
12199 | |||
12200 | >7&®!=(int)itok.number){ |
||
12201 | |||
12202 | >=EBX&&tok==tk_bytevar&&optimizespeed&&chip>7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ |
||
12203 | |||
12204 | >3)cpu=3; |
||
12205 | |||
12206 | |||
12207 | |||
12208 | >32){ |
||
12209 | |||
12210 | >2;i++){ |
||
12211 | |||
12212 | >2;i++){ |
||
12213 | |||
12214 | >0x100000000LL){ |
||
12215 | |||
12216 | >256&&r1<4){ |
||
12217 | |||
12218 | >2;i++){ |
||
12219 | |||
12220 | } |
||
12221 | |||
12222 | void>2;i++){ |
||
12223 | |||
12224 | >32){ |
||
12225 | |||
12226 | >2;i++){ |
||
12227 | |||
12228 | >2;i++){ |
||
12229 | |||
12230 | >3)cpu=3; |
||
12231 | |||
12232 | >2;i++){ |
||
12233 | |||
12234 | >2;i++){ |
||
12235 | |||
12236 | >2;i++){ |
||
12237 | |||
12238 | >2;i++){ |
||
12239 | |||
12240 | >2;i++){ |
||
12241 | |||
12242 | >2;i++){ |
||
12243 | |||
12244 | >=tk_float)tok=tk_charvar+itok.type-tk_char; |
||
12245 | |||
12246 | >65536&&razr==r32)razr=r16; |
||
12247 | |||
12248 | >65536&&razr==r32)skip66=TRUE; |
||
12249 | |||
12250 | >9){ |
||
12251 | |||
12252 | > |
||
12253 | |||
12254 | >=32)next=r32; |
||
12255 | |||
12256 | >2)regmathoperror(); |
||
12257 | |||
12258 | >=16)vops=r16; |
||
12259 | |||
12260 | >=64)vops=r64; |
||
12261 | |||
12262 | >2&&razr==r16)regmathoperror(); |
||
12263 | |||
12264 | >2)cpu=2; |
||
12265 | |||
12266 | > |
||
12267 | |||
12268 | >4&&tok2!=tk_floatvar&&tok2!=tk_doublevar&&tok2!=tk_float&&tok2!=tk_double)op(0x9B); |
||
12269 | |||
12270 | |||
12271 | |||
12272 | > |
||
12273 | |||
12274 | >4){ |
||
12275 | |||
12276 | >7&&itok.number!=AL&&itok.number!=AH){ |
||
12277 | |||
12278 | >3)cpu=3; |
||
12279 | |||
12280 | } |
||
12281 | |||
12282 | void>3)cpu=3; |
||
12283 | |||
12284 | > |
||
12285 | |||
12286 | >=16)vops=r16; |
||
12287 | |||
12288 | >=64)vops=r64; |
||
12289 | |||
12290 | >=tk_doublevar&&itok.npointr==0){ |
||
12291 | |||
12292 | >7&®<4&®!=(int)(itok.number%4)){ |
||
12293 | |||
12294 | >=16)vops=r16; |
||
12295 | |||
12296 | >=64)vops=r64; |
||
12297 | |||
12298 | >=BX){ |
||
12299 | |||
12300 | >=EBX&&tok==tk_bytevar&&optimizespeed&&chip>7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ |
||
12301 | |||
12302 | >1)cpu=1; |
||
12303 | |||
12304 | >2)cpu=2; |
||
12305 | |||
12306 | >=8)vops=r8; |
||
12307 | |||
12308 | >=32)vops=r32; |
||
12309 | |||
12310 | >=tk_doublevar&&itok2.npointr==0){ |
||
12311 | |||
12312 | } |
||
12313 | |||
12314 | void>2&&razr==r16){ |
||
12315 | |||
12316 | > |
||
12317 | |||
12318 | >=32)vops=r32; |
||
12319 | |||
12320 | >3)cpu=3;>3)cpu=3;>3)cpu=3;>3)cpu=3;>"); |
||
12321 | |||
12322 | >3)cpu=3; |
||
12323 | |||
12324 | >4?beg:beg-4; |
||
12325 | |||
12326 | >4){ |
||
12327 | |||
12328 | >65536&&razr==r32)nrazr=razr=r16; |
||
12329 | |||
12330 | //>2&&razr==r16){ |
||
12331 | |||
12332 | >2)cpu=2; |
||
12333 | |||
12334 | >=BX){ |
||
12335 | |||
12336 | >2)>=8)razr=r8; |
||
12337 | |||
12338 | >=32)razr=r32; |
||
12339 | |||
12340 | >1)cpu=1; |
||
12341 | |||
12342 | >=8)razr=r8; |
||
12343 | |||
12344 | >=32)razr=r32; |
||
12345 | |||
12346 | >2)cpu=2; |
||
12347 | |||
12348 | >=8)razr=r8; |
||
12349 | |||
12350 | >=32)razr=r32; |
||
12351 | |||
12352 | >=tk_doublevar&&itok2.npointr==0){ |
||
12353 | |||
12354 | >3)cpu=3; |
||
12355 | |||
12356 | >=16)razr=r16; |
||
12357 | |||
12358 | >=64)razr=r64; |
||
12359 | |||
12360 | } |
||
12361 | |||
12362 | void> |
||
12363 | |||
12364 | >=32)vops=r32; |
||
12365 | |||
12366 | > |
||
12367 | |||
12368 | >=32)vops=r32; |
||
12369 | |||
12370 | > |
||
12371 | |||
12372 | >3)cpu=3; |
||
12373 | |||
12374 | |||
12375 | |||
12376 | >7){ |
||
12377 | |||
12378 | >=16)i=r16; |
||
12379 | |||
12380 | >=64)i=r64; |
||
12381 | |||
12382 | >2){ |
||
12383 | |||
12384 | >3)cpu=3; |
||
12385 | |||
12386 | >2&&razr==r16){ |
||
12387 | |||
12388 | > |
||
12389 | |||
12390 | >4)||usereg==0){ |
||
12391 | |||
12392 | >4)ureg=hnumber=itok.number; |
||
12393 | |||
12394 | > |
||
12395 | |||
12396 | >9){ |
||
12397 | |||
12398 | >2)||(*expand==TRUE)){ |
||
12399 | |||
12400 | num_imul: |
||
12401 | |||
12402 | >3&&razr==r16){ |
||
12403 | |||
12404 | > |
||
12405 | |||
12406 | >3&&rflag==0&&posttok.post==0)goto>128){ |
||
12407 | |||
12408 | >3||val>0xffffff80>0xffffff80))>128)goto>3){ |
||
12409 | |||
12410 | ><3)+base); |
||
12411 | |||
12412 | ><6)+(idx<<3)+base); |
||
12413 | |||
12414 | ><6)); |
||
12415 | |||
12416 | > |
||
12417 | |||
12418 | > |
||
12419 | |||
12420 | >7)return> |
||
12421 |