Subversion Repositories Kolibri OS

Rev

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 */
12195
 
12196
>
12197
 
12198
>
12199
 
12200
>
12201
 
12202
>
12203
 
12204
>
12205
 
12206
12207
 
12208
>
12209
 
12210
>
12211
 
12212
>
12213
 
12214
>
12215
 
12216
>
12217
 
12218
>
12219
 
12220
}
12221
 
12222
void>
12223
 
12224
>
12225
 
12226
>
12227
 
12228
>
12229
 
12230
>
12231
 
12232
>
12233
 
12234
>
12235
 
12236
>
12237
 
12238
>
12239
 
12240
>
12241
 
12242
>
12243
 
12244
>
12245
 
12246
>
12247
 
12248
>
12249
 
12250
>
12251
 
12252
>
12253
 
12254
>
12255
 
12256
>
12257
 
12258
>
12259
 
12260
>
12261
 
12262
>
12263
 
12264
>
12265
 
12266
>
12267
 
12268
>
12269
 
12270
12271
 
12272
>
12273
 
12274
>
12275
 
12276
>
12277
 
12278
>
12279
 
12280
}
12281
 
12282
void>
12283
 
12284
>
12285
 
12286
>
12287
 
12288
>
12289
 
12290
>
12291
 
12292
>
12293
 
12294
>
12295
 
12296
>
12297
 
12298
>
12299
 
12300
>
12301
 
12302
>
12303
 
12304
>
12305
 
12306
>
12307
 
12308
>
12309
 
12310
>
12311
 
12312
}
12313
 
12314
void>
12315
 
12316
>
12317
 
12318
>
12319
 
12320
>
12321
 
12322
>
12323
 
12324
>
12325
 
12326
>
12327
 
12328
>
12329
 
12330
//>
12331
 
12332
>
12333
 
12334
>
12335
 
12336
>
12337
 
12338
>
12339
 
12340
>
12341
 
12342
>
12343
 
12344
>
12345
 
12346
>
12347
 
12348
>
12349
 
12350
>
12351
 
12352
>
12353
 
12354
>
12355
 
12356
>
12357
 
12358
>
12359
 
12360
}
12361
 
12362
void>
12363
 
12364
>
12365
 
12366
>
12367
 
12368
>
12369
 
12370
>
12371
 
12372
>
12373
 
12374
12375
 
12376
>
12377
 
12378
>
12379
 
12380
>
12381
 
12382
>
12383
 
12384
>
12385
 
12386
>
12387
 
12388
>
12389
 
12390
>
12391
 
12392
>
12393
 
12394
>
12395
 
12396
>
12397
 
12398
>
12399
 
12400
num_imul:
12401
 
12402
>
12403
 
12404
>
12405
 
12406
>
12407
 
12408
>
12409
 
12410
>
12411
 
12412
>
12413
 
12414
>
12415
 
12416
>
12417
 
12418
>
12419
 
12420
>
12421