Subversion Repositories Kolibri OS

Rev

Rev 6446 | Rev 7626 | 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
 
1387
					if((flag&f_reloc)!=0)AddReloc();
1388
 
1389
				 	op66(razr);
1390
 
1391
					else outword(0xE1F7); /* MUL CX */
1392
 
1393
					warningreg(regs[razr/2-1][1]);
1394
 
1395
				else{
1396
 
1397
					op(0x90+reg);	//XCHG AX,reg
1398
 
1399
					op(reg!=DX?0xBA:0xB9);
1400
 
1401
					op66(r16);
1402
 
1403
					op(reg!=DX?0xE2:0xE1);	// mul DX
1404
 
1405
					op(0x90+reg);	//XCHG AX,reg
1406
 
1407
					ClearReg(DX);
1408
 
1409
			}
1410
 
1411
				if((flag&f_reloc)==0&&short_ok(num,razr/2-1))i=2;	//короткая форма
1412
 
1413
				op(0x69+i);	//imul
1414
 
1415
				if(i==2)op(num);
1416
 
1417
					if((flag&f_reloc)!=0)AddReloc();
1418
 
1419
				}
1420
 
1421
			setzeroflag=FALSE;
1422
 
1423
	}
1424
 
1425
1426
 
1427
1428
 
1429
{
1430
 
1431
	switch(sign){
1432
 
1433
			hold=doconstdwordmath();
1434
 
1435
		case 1:
1436
 
1437
			break;
1438
 
1439
			hold=doconstfloatmath();
1440
 
1441
		case 3:
1442
 
1443
			break;
1444
 
1445
			hold=doconstqwordmath();
1446
 
1447
	}
1448
 
1449
}
1450
 
1451
int OnlyNumber(int sign)
1452
 
1453
 проверить что строка состоит только из цифр.
1454
 
1455
{
1456
 
1457
unsigned char ocha=cha2;
1458
 
1459
unsigned int otok2=tok2;
1460
 
1461
	itok.lnumber=CalcNumber(sign);
1462
 
1463
	if(itok.type==tp_stopper){
1464
 
1465
	}
1466
 
1467
	inptr2=oinptr;
1468
 
1469
	tok=tk_number;
1470
 
1471
 
1472
 
1473
		free(bufrm);
1474
 
1475
	}
1476
 
1477
		free(strinf.bufstr);
1478
 
1479
	}
1480
 
1481
}
1482
 
1483
void MultiAssignFloat(int type,int npointr=0)
1484
 
1485
int otok;
1486
 
1487
char *wbuf;
1488
 
1489
char *ofsstr=NULL;
1490
 
1491
	wstr=strinf;
1492
 
1493
	wtok=itok;
1494
 
1495
	bufrm=NULL;
1496
 
1497
	nexttok();
1498
 
1499
int numpointr=0;
1500
 
1501
	if(tok==tk_float||tok==tk_double)nexttok();
1502
 
1503
		nexttok();
1504
 
1505
	}
1506
 
1507
	if(tok2==tk_assign)MultiAssignFloat(type,numpointr);
1508
 
1509
		if(tok==tk_pointer)cpointr(BX,numpointr);
1510
 
1511
			tok=tk_dwordvar;
1512
 
1513
		}
1514
 
1515
	}
1516
 
1517
		if(wtok.type==tk_proc){
1518
 
1519
			if(am32)wtok.sib=CODE32;
1520
 
1521
			compressoffset(&wtok);
1522
 
1523
		else{
1524
 
1525
			if(npointr<=wtok.npointr)getpointeradr(&wtok,wbuf,&wstr,npointr-1,razr,BX);
1526
 
1527
			wtok=itok;
1528
 
1529
	}
1530
 
1531
		op66(r32);
1532
 
1533
		op(0xA3); /* MOV [word],AX */
1534
 
1535
			AddUndefOff(2,wtok.name);
1536
 
1537
		}
1538
 
1539
		else outdword(wtok.number);
1540
 
1541
	else{
1542
 
1543
		op66(r32);
1544
 
1545
		op(0x89); op(wtok.rm); /* MOV [rmword],reg */
1546
 
1547
	}
1548
 
1549
1550
 
1551
{
1552
 
1553
ITOK wtok;
1554
 
1555
SINFO wstr;
1556
 
1557
int hnumber=0;
1558
 
1559
char *ofsstr=NULL;
1560
 
1561
	strinf.bufstr=NULL;
1562
 
1563
	wbuf=bufrm;
1564
 
1565
	otok=tok;
1566
 
1567
		usereg=EAX;//USEONLY_AX;
1568
 
1569
		rettype=tk_dword;
1570
 
1571
		if(i<9){
1572
 
1573
			rettype=tk_byte;
1574
 
1575
		else if(i<17){
1576
 
1577
			nrazr=r16;
1578
 
1579
		else if(i>32)nrazr=r64;
1580
 
1581
	else{
1582
 
1583
		switch(tok){
1584
 
1585
				ureg=itok.number;
1586
 
1587
				if(usereg>ureg)usereg=ureg;
1588
 
1589
			case tk_reg:
1590
 
1591
				if(usereg>itok.number)usereg=itok.number;
1592
 
1593
		}
1594
 
1595
	}
1596
 
1597
	if(nrazr>razr&&nrazr
1598
 
1599
		case r8:
1600
 
1601
			break;
1602
 
1603
			rettype=tk_word;
1604
 
1605
		case r32:
1606
 
1607
			break;
1608
 
1609
	nexttok();
1610
 
1611
	ofsstr=GetLecsem(tk_assign,tk_semicolon);
1612
 
1613
	convert_type(&sign,&rettype,&pointr);
1614
 
1615
		nexttok();
1616
 
1617
	}
1618
 
1619
		unuseableinput();
1620
 
1621
	ureg=AX;
1622
 
1623
		ureg=hnumber=MultiAssign(razr,usereg,numpointr);
1624
 
1625
			free(ofsstr);
1626
 
1627
		}
1628
 
1629
	else{
1630
 
1631
			int reg=idxregs[2];
1632
 
1633
			cpointr(reg,numpointr);
1634
 
1635
		if(usereg==USEALLREG){
1636
 
1637
				case tk_reg:
1638
 
1639
					usereg=itok.number;
1640
 
1641
				case tk_beg:
1642
 
1643
					break;
1644
 
1645
					usereg=EAX;
1646
 
1647
			}
1648
 
1649
		switch(rettype){
1650
 
1651
			case tk_byte:
1652
 
1653
					ureg=hnumber=usereg;
1654
 
1655
					getintoreg(usereg,r16,sign,&ofsstr);
1656
 
1657
/*				if(tok2==tk_semicolon&&tok==tk_beg&&usereg<2){
1658
 
1659
						ureg=hnumber=itok.number;
1660
 
1661
						break;
1662
 
1663
				}*/
1664
 
1665
				if(ofsstr)IDZToReg(ofsstr,usereg,r8);
1666
 
1667
			case tk_int:
1668
 
1669
				if(tok2==tk_semicolon&&usereg!=0){
1670
 
1671
//					if(tok==tk_reg)ureg=hnumber=itok.number;
1672
 
1673
				}
1674
 
1675
				if(ofsstr)IDZToReg(ofsstr,usereg,r16);
1676
 
1677
			case tk_float:
1678
 
1679
				break;
1680
 
1681
				if(tok2==tk_semicolon&&usereg!=0&&tok!=tk_floatvar){
1682
 
1683
//					if(tok==tk_reg32)ureg=hnumber=itok.number;
1684
 
1685
				}
1686
 
1687
					if(tok==tk_floatvar&&tok2==tk_semicolon)tok=tk_dwordvar;
1688
 
1689
				}
1690
 
1691
				break;
1692
 
1693
	}
1694
 
1695
		free(ofsstr);
1696
 
1697
	}
1698
 
1699
		case r8:
1700
 
1701
			break;
1702
 
1703
			posiblret=tk_word;
1704
 
1705
		case r32:
1706
 
1707
			break;
1708
 
1709
	convert_returnvalue(posiblret,rettype);
1710
 
1711
	switch ( otok ) {
1712
 
1713
		case tk_wordvar:
1714
 
1715
		case tk_dwordvar:
1716
 
1717
#ifdef OPTVARCONST
1718
 
1719
#endif
1720
 
1721
			AddRegVar(hnumber,razr,&wtok);
1722
 
1723
				op66(nrazr);
1724
 
1725
				op(0xA3); /* MOV [word],AX */
1726
 
1727
					AddUndefOff(2,wtok.name);
1728
 
1729
				}
1730
 
1731
				else outdword(wtok.number);
1732
 
1733
			else{
1734
 
1735
				op66(nrazr);
1736
 
1737
				op(0x89); op(wtok.rm+hnumber*8); /* MOV [rmword],reg */
1738
 
1739
			}
1740
 
1741
		case tk_charvar:
1742
 
1743
#ifdef OPTVARCONST
1744
 
1745
#endif
1746
 
1747
			AddRegVar(hnumber,r8,&wtok);
1748
 
1749
				outseg(&wtok,1);
1750
 
1751
				if(wtok.post==UNDEF_OFSET){
1752
 
1753
					wtok.post=0;
1754
 
1755
				if(am32==FALSE)outword(wtok.number);
1756
 
1757
			}
1758
 
1759
				CheckAllMassiv(wbuf,1,&wstr,&wtok);
1760
 
1761
				op(0x88);
1762
 
1763
				outaddress(&wtok);
1764
 
1765
			break;
1766
 
1767
			if(razr!=r64){
1768
 
1769
				op(0x50);	//push eax
1770
 
1771
				reg2bits(&wtok,razr);
1772
 
1773
				op(0x58);	//pop eax
1774
 
1775
			else{
1776
 
1777
				op(0x50);	//push eax
1778
 
1779
				op66(r32);
1780
 
1781
 
1782
 
1783
				reg2bits(&wtok,r32);
1784
 
1785
				op(0x58);	//pop eax
1786
 
1787
				outword(0xE8C1);
1788
 
1789
				wtok.bit.siz=siz+wtok.bit.ofs-32;
1790
 
1791
				wtok.number+=4;
1792
 
1793
				op66(r32);
1794
 
1795
			}
1796
 
1797
		case tk_reg:
1798
 
1799
			if(wtok.number!=hnumber){
1800
 
1801
					op66(nrazr);
1802
 
1803
					op(0xC0+wtok.number+hnumber*8);	//mov reg,AX
1804
 
1805
				else waralreadinitreg(regs[nrazr/4][wtok.number],regs[nrazr/4][hnumber]);
1806
 
1807
			break;
1808
 
1809
			if(razr>r8&&wtok.number>3&&(wtok.number%4)==hnumber)preerror("register AH,BH,CH,DH should be first");
1810
 
1811
				if(RegToReg(hnumber,wtok.number,r8)==NOINREG){
1812
 
1813
					op(0xC0+wtok.number+hnumber*8);	//mov beg,AL
1814
 
1815
				else waralreadinitreg(begs[wtok.number],begs[hnumber]);
1816
 
1817
			break;
1818
 
1819
			op(0x8E); 	/* MOV SEG,AX */
1820
 
1821
			break;
1822
 
1823
			thisundefined(wtok.name);
1824
 
1825
	return hnumber;
1826
 
1827
1828
 
1829
{
1830
 
1831
unsigned int vop=0,otok,rettype,posiblret;
1832
 
1833
char *wbuf,*rbuf;
1834
 
1835
int retrez=0,pointr=0,hnumber=EAX;
1836
 
1837
char *ofsstr=NULL;
1838
 
1839
#ifdef OPTVARCONST
1840
 
1841
int operand;
1842
 
1843
unsigned int oaddESP=addESP;
1844
 
1845
	posiblret=rettype=(sign==0?(razr==r16?tk_word:tk_dword):(razr==r16?tk_int:tk_long));
1846
 
1847
	strinf.bufstr=NULL;
1848
 
1849
	wbuf=bufrm;
1850
 
1851
	otok=tok;
1852
 
1853
	nexttok();
1854
 
1855
	operand=tok;
1856
 
1857
	switch(tok){
1858
 
1859
			if(!((tok2==tk_reg||tok2==tk_reg32)&&ScanTok3()==terminater)){
1860
 
1861
			}
1862
 
1863
				int retreg;
1864
 
1865
					GetEndLex(terminater);
1866
 
1867
					if((GetRegVar(&wtok)&(1<
1868
 
1869
						if(wbuf)free(wbuf);
1870
 
1871
						break;
1872
 
1873
					if(razr==r16)tok=tk_reg;
1874
 
1875
					itok.number=retreg;
1876
 
1877
						reg1=idxregs[1]; reg2=idxregs[2];
1878
 
1879
					if(reg2==itok.number){
1880
 
1881
					}
1882
 
1883
				}
1884
 
1885
			nexttok();
1886
 
1887
			convert_type(&sign,(int *)&rettype,&pointr);
1888
 
1889
				nexttok();
1890
 
1891
			}
1892
 
1893
				unuseableinput();
1894
 
1895
			if(tok2==tk_assign){
1896
 
1897
				if(ofsstr){
1898
 
1899
					ofsstr=NULL;
1900
 
1901
				next=0;
1902
 
1903
 
1904
 
1905
			CheckMinusNum();
1906
 
1907
			if(itok2.type==tp_opperand){	//сложное выражение
1908
 
1909
					if(OnlyNumber(rettype==tk_float?2:sign)){
1910
 
1911
						itok.flag=(unsigned char)postnumflag;
1912
 
1913
						goto numbertovar;
1914
 
1915
				}
1916
 
1917
			}
1918
 
1919
//		 		if(hnumber!=EAX&&(tok==tk_reg||tok==tk_reg32)&&itok.number==EAX)goto labl1;
1920
 
1921
				CheckConstVar3(&tok,&itok,razr);
1922
 
1923
				switch(tok){
1924
 
1925
loadconst:
1926
 
1927
#ifdef OPTVARCONST
1928
 
1929
							else itok.lnumber&=0xffffffff;
1930
 
1931
								waralreadinitvar(wtok.name,itok.number);
1932
 
1933
								break;
1934
 
1935
#endif
1936
 
1937
		 						CheckAllMassiv(wbuf,razr,&wstr,&wtok);
1938
 
1939
								outseg(&wtok,2);
1940
 
1941
								op(wtok.rm+0x20);
1942
 
1943
								op(0);
1944
 
1945
							}
1946
 
1947
 
1948
 
1949
								outseg(&wtok,2);
1950
 
1951
								op(wtok.rm+0x8);
1952
 
1953
								op(0xFF);
1954
 
1955
							}
1956
 
1957
								CheckAllMassiv(wbuf,razr,&wstr,&wtok);
1958
 
1959
								op(0x6A);
1960
 
1961
								op66(razr);
1962
 
1963
								op(0x8f);
1964
 
1965
								outaddress(&wtok);
1966
 
1967
							}
1968
 
1969
					case tk_postnumber:
1970
 
1971
numbertovar:
1972
 
1973
						op66(razr);
1974
 
1975
						op(0xC7);	//mov word[],number
1976
 
1977
						outaddress(&wtok);
1978
 
1979
						else if(tok==tk_undefofs)AddUndefOff(0,itok.name);
1980
 
1981
						if(razr==r16){
1982
 
1983
							outword((unsigned int)itok.number);
1984
 
1985
						else outdword(itok.number);
1986
 
1987
					case tk_apioffset:
1988
 
1989
						op66(razr);
1990
 
1991
						op(0xC7);	//mov word[],number
1992
 
1993
						outaddress(&wtok);
1994
 
1995
						break;
1996
 
1997
//						if(razr==r16)goto labl1;
1998
 
1999
						if(razr==r32&&tok==tk_reg)goto labl1;
2000
 
2001
						if((unsigned int)itok.number==0){
2002
 
2003
							hnumber=0;
2004
 
2005
						else{
2006
 
2007
								KillVar(wtok.name);
2008
 
2009
								vop++;
2010
 
2011
							CheckAllMassiv(wbuf,razr,&wstr,&wtok,reg1,reg2);
2012
 
2013
							outseg(&wtok,2);
2014
 
2015
							op((unsigned int)itok.number*8+wtok.rm);
2016
 
2017
						}
2018
 
2019
					case tk_seg:
2020
 
2021
						CheckAllMassiv(wbuf,2,&wstr,&wtok);
2022
 
2023
						outseg(&wtok,2);
2024
 
2025
						op((unsigned int)itok.number*8+wtok.rm);
2026
 
2027
						if((unsigned int)itok.number==FS||(unsigned int)itok.number==GS)if(cpu<3)cpu=3;
2028
 
2029
					case tk_string:
2030
 
2031
						op66(razr);
2032
 
2033
						op(0xC7);
2034
 
2035
						outaddress(&wtok);
2036
 
2037
							if(am32)dwordvalexpected();
2038
 
2039
						}
2040
 
2041
						break;
2042
 
2043
						vop=4;
2044
 
2045
						intinstack(vop);
2046
 
2047
						CheckAllMassiv(wbuf,4,&wstr,&wtok);
2048
 
2049
						op(razr==r16?0xDF:0xDB);
2050
 
2051
						outaddress(&wtok);
2052
 
2053
						fwait3();
2054
 
2055
						break;
2056
 
2057
						donew();
2058
 
2059
						clearregstat();
2060
 
2061
						FreeGlobalConst();
2062
 
2063
						if(ofsstr){
2064
 
2065
							ofsstr=NULL;
2066
 
2067
						hnumber=0;
2068
 
2069
					case tk_delete:
2070
 
2071
						terminater=next=0;
2072
 
2073
						clearregstat();
2074
 
2075
						FreeGlobalConst();
2076
 
2077
						if(ofsstr)free(ofsstr);
2078
 
2079
						break;
2080
 
2081
					case tk_dwordvar:
2082
 
2083
						goto labl1;
2084
 
2085
					case tk_wordvar:
2086
 
2087
pushvar:
2088
 
2089
							op66(razr);
2090
 
2091
							op(0xFF);	// PUSH [dword]
2092
 
2093
							outaddress(&itok);
2094
 
2095
							op66(razr);
2096
 
2097
							op(0x8f);
2098
 
2099
							outaddress(&wtok);
2100
 
2101
						}
2102
 
2103
					default:
2104
 
2105
						getfromAX=1;
2106
 
2107
							if(hnumber==0)retrez=doalmath(sign,&ofsstr);
2108
 
2109
								retrez=getintoreg(hnumber,razr,sign,&ofsstr);
2110
 
2111
							}
2112
 
2113
						else if(rettype==tk_int||rettype==tk_word){
2114
 
2115
							else retrez=getintoreg(hnumber,r16,sign,&ofsstr);
2116
 
2117
 
2118
 
2119
							getfromAX=0;
2120
 
2121
							outseg(&wtok,2);	//fistp var
2122
 
2123
							op(wtok.rm+0x18);
2124
 
2125
							if(sign==0)warningretsign();
2126
 
2127
							hnumber=EAX;
2128
 
2129
						else{
2130
 
2131
							else retrez=getintoreg(hnumber,r32,sign,&ofsstr);
2132
 
2133
						next=0;
2134
 
2135
				}
2136
 
2137
			if(getfromAX){
2138
 
2139
#ifdef OPTVARCONST
2140
 
2141
#endif
2142
 
2143
				convert_returnvalue(posiblret,rettype);
2144
 
2145
				if(wbuf==NULL&&wstr.bufstr==NULL&&hnumber==0&&
2146
 
2147
						(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){
2148
 
2149
					outseg(&wtok,1);
2150
 
2151
					if(wtok.post==UNDEF_OFSET){
2152
 
2153
						wtok.post=0;
2154
 
2155
					if(am32==FALSE)outword(wtok.number);	//????
2156
 
2157
				}
2158
 
2159
					CheckAllMassiv(wbuf,razr,&wstr,&wtok,reg1,reg2);
2160
 
2161
					op66(razr);
2162
 
2163
					op(0x89); op(wtok.rm+hnumber*8); // MOV [rmword],AX
2164
 
2165
				}
2166
 
2167
				else ClearReg(hnumber);
2168
 
2169
				AddRegVar(hnumber,razr,&wtok);
2170
 
2171
			else{
2172
 
2173
				if(vop==0)KillVar(wtok.name);
2174
 
2175
			if(ofsstr)free(ofsstr);
2176
 
2177
		case tk_minusminus: vop=0x8;
2178
 
2179
#ifdef OPTVARCONST
2180
 
2181
#endif
2182
 
2183
			op66(razr);
2184
 
2185
			op(0xFF); op(vop+wtok.rm);
2186
 
2187
			KillVar(wtok.name);
2188
 
2189
		case tk_cdecl:
2190
 
2191
		case tk_fastcall:
2192
 
2193
			vop=tok;
2194
 
2195
			if(tok!=tk_openbracket){
2196
 
2197
				FindStopTok();
2198
 
2199
		case tk_openbracket:	//вызов процедуры по адресу в регистре
2200
 
2201
			int i;
2202
 
2203
			switch ( vop ) {
2204
 
2205
				case tk_stdcall:
2206
 
2207
					break;
2208
 
2209
					doparams();
2210
 
2211
				case tk_fastcall:
2212
 
2213
					break;
2214
 
2215
					if(comfile==file_w32)swapparam();
2216
 
2217
			}
2218
 
2219
			CheckAllMassiv(wbuf,razr,&wstr,&wtok);
2220
 
2221
			op(0xFF); op(0x10+wtok.rm);
2222
 
2223
			clearregstat();
2224
 
2225
			FreeGlobalConst();
2226
 
2227
			if(i)CorrectStack(i);
2228
 
2229
		case tk_xorequals: vop+=0x08;
2230
 
2231
		case tk_andequals: vop+=0x18;
2232
 
2233
		case tk_plusequals:
2234
 
2235
			if(tok==tk_float){
2236
 
2237
				doeaxfloatmath(tk_reg32,AX);
2238
 
2239
			}
2240
 
2241
				if(tok==tk_number){
2242
 
2243
						next=0;
2244
 
2245
						tok=tk_number;
2246
 
2247
					}
2248
 
2249
				retrez=razr==r16?tk_reg:tk_reg32;
2250
 
2251
 
2252
 
2253
				CheckAllMassiv(wbuf,razr,&wstr,&wtok);
2254
 
2255
				outseg(&wtok,2);
2256
 
2257
				outaddress(&wtok);
2258
 
2259
			}
2260
 
2261
				switch(tok){
2262
 
2263
					case tk_postnumber:
2264
 
2265
num:
2266
 
2267
						if(tok==tk_number&&(itok.flag&f_reloc)==0){
2268
 
2269
						}
2270
 
2271
						CheckAllMassiv(wbuf,razr,&wstr,&wtok);
2272
 
2273
						outseg(&wtok,2);
2274
 
2275
							if(vop)vop=8;
2276
 
2277
							outaddress(&wtok);
2278
 
2279
						else if(tok!=tk_undefofs&&tok!=tk_postnumber&&(itok.flag&f_reloc)==0&&
2280
 
2281
							op(0x83);
2282
 
2283
							outaddress(&wtok);
2284
 
2285
						}
2286
 
2287
							op(0x81);
2288
 
2289
							outaddress(&wtok);
2290
 
2291
							else if(tok==tk_undefofs)AddUndefOff(0,itok.name);
2292
 
2293
							razr==r16?outword(itok.number):outdword(itok.number);
2294
 
2295
						if(next==0)tok=otok;
2296
 
2297
					case tk_apioffset:
2298
 
2299
						op66(razr);
2300
 
2301
						op(0x81);
2302
 
2303
						outaddress(&wtok);
2304
 
2305
						break;
2306
 
2307
						if(razr==r16)goto defxor;
2308
 
2309
						if(tok==tk_reg&&razr==r32)goto defxor;
2310
 
2311
						initconst=CheckUpdRegToConst(itok.number,&wtok,operand,razr);
2312
 
2313
						CheckAllMassiv(wbuf,razr,&wstr,&wtok);
2314
 
2315
						outseg(&wtok,2);
2316
 
2317
						outaddress(&wtok);
2318
 
2319
					default:
2320
 
2321
						retrez=razr==r16?tk_reg:tk_reg32;
2322
 
2323
						if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP;
2324
 
2325
						op66(razr);
2326
 
2327
						op(0x01+vop); op(wtok.rm);  /* ADD [anyword],AX */
2328
 
2329
						next=0;
2330
 
2331
				}
2332
 
2333
//			puts(wtok.name);
2334
 
2335
			break;
2336
 
2337
			getoperand(am32==TRUE?EAX:BX);
2338
 
2339
				if(tok==tk_number){
2340
 
2341
					if(itok.number==0){
2342
 
2343
						goto getfromax;
2344
 
2345
#ifdef OPTVARCONST
2346
 
2347
						initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand);
2348
 
2349
#endif
2350
 
2351
					else getinto_reg(otok,&wtok,wbuf,&wstr,razr,hnumber);
2352
 
2353
					RegMulNum(hnumber,itok.number,razr,sign,(int *)&vop,itok.flag);
2354
 
2355
				}
2356
 
2357
			if(hnumber==0)do_e_axmath(sign,razr,&ofsstr);
2358
 
2359
			if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar)){
2360
 
2361
				oaddESP=addESP;
2362
 
2363
			CheckAllMassiv(wbuf,razr,&wstr,&wtok);
2364
 
2365
			if(hnumber==0){
2366
 
2367
				op(0xF7);	// imul/mul var
2368
 
2369
				else op(0x20+wtok.rm);
2370
 
2371
			else{
2372
 
2373
				outword(0xaf0f);
2374
 
2375
			}
2376
 
2377
			next=0;
2378
 
2379
			goto getfromax;
2380
 
2381
			getoperand(am32==TRUE?EAX:BX);
2382
 
2383
			if(itok2.type==tp_stopper){
2384
 
2385
					if(itok.number==1)break;
2386
 
2387
					if((itok.flag&f_reloc)==0){
2388
 
2389
					}
2390
 
2391
					getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE);
2392
 
2393
					next=0;
2394
 
2395
				}
2396
 
2397
			}
2398
 
2399
				do_e_axmath(sign,razr,&ofsstr);
2400
 
2401
				else op(0x90+ECX);	//xchg ax,Cx
2402
 
2403
					wtok.number+=addESP-oaddESP;
2404
 
2405
				}
2406
 
2407
			getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE);
2408
 
2409
			op66(razr);
2410
 
2411
			if(sign)op(0xF8+ECX); // IDIV CX
2412
 
2413
			next=0;
2414
 
2415
			KillVar(wtok.name);
2416
 
2417
		case tk_swap:
2418
 
2419
			int regdi;
2420
 
2421
			getoperand();
2422
 
2423
			bufrm=NULL;
2424
 
2425
			switch(tok){
2426
 
2427
					if(razr==r16)swaperror();
2428
 
2429
					if(tok==tk_reg&&razr==r32)swaperror();
2430
 
2431
					initconst=SwapVarRegConst(itok.number,&wtok,razr);
2432
 
2433
					CheckAllMassiv(wbuf,razr,&wstr,&wtok);
2434
 
2435
					outseg(&wtok,2);
2436
 
2437
					op((unsigned int)itok.number*8+wtok.rm);
2438
 
2439
					ClearReg(itok.number);
2440
 
2441
				case tk_qwordvar:
2442
 
2443
				case tk_dwordvar:
2444
 
2445
				case tk_intvar:
2446
 
2447
					if((tok==tk_intvar||tok==tk_wordvar)&&razr==r32)swaperror();
2448
 
2449
					ClearVarByNum(&itok);
2450
 
2451
					if(hnumber==0)getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE);
2452
 
2453
						if(regoverstack&&(!((bufrm||strinf.bufstr)&&(wbuf||wstr.bufstr)))){
2454
 
2455
							op66(razr);
2456
 
2457
							op(0xFF);	// PUSH [dword]
2458
 
2459
							outaddress(&itok);
2460
 
2461
							op66(razr);
2462
 
2463
							op(0xFF);	// PUSH [dword]
2464
 
2465
							outaddress(&wtok);
2466
 
2467
							CheckAllMassiv(bufrm,razr,&strinf);
2468
 
2469
							outseg(&itok,2);
2470
 
2471
							op(itok.rm);
2472
 
2473
							CheckAllMassiv(wbuf,razr,&wstr,&wtok);
2474
 
2475
							outseg(&wtok,2);
2476
 
2477
							op(wtok.rm);
2478
 
2479
2480
 
2481
						}
2482
 
2483
					}
2484
 
2485
					op66(razr);
2486
 
2487
					op(0x87);  /* XCHG AX,[wloc] */
2488
 
2489
					outaddress(&itok);
2490
 
2491
				case tk_seg:
2492
 
2493
					op66(r16);
2494
 
2495
					op(0xC0+(unsigned int)itok.number*8);
2496
 
2497
					op66(r16);
2498
 
2499
 
2500
 
2501
					outaddress(&wtok);
2502
 
2503
					op(0x8E); /* MOV seg,AX */
2504
 
2505
					break;
2506
 
2507
					if(razr==r16)swaperror();
2508
 
2509
						CheckAllMassiv(wbuf,4,&wstr,&wtok);
2510
 
2511
						op(0xDB);
2512
 
2513
						outaddress(&wtok);
2514
 
2515
						outseg(&itok,2);	//fld val
2516
 
2517
						op(itok.rm);
2518
 
2519
					}
2520
 
2521
						CheckInitBP();
2522
 
2523
						outword(0x6a);
2524
 
2525
						op66(r32);	//push var
2526
 
2527
						addESP+=8;
2528
 
2529
						op(0xFF);
2530
 
2531
						outaddress(&wtok);
2532
 
2533
						CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]);
2534
 
2535
						op(0xd9);
2536
 
2537
						outaddress(&itok);
2538
 
2539
						if(optimizespeed||am32==0){
2540
 
2541
							op(8);
2542
 
2543
						else{
2544
 
2545
							op(0x58);	// pop EAX
2546
 
2547
 
2548
 
2549
					outseg(&wtok,2);//fistp var
2550
 
2551
					op(wtok.rm+0x18);
2552
 
2553
					outseg(&itok,2);	//fstp val
2554
 
2555
					op(itok.rm+0x18);
2556
 
2557
					fwait3();
2558
 
2559
				default: swaperror(); break;
2560
 
2561
			break;
2562
 
2563
			vop=8;
2564
 
2565
		case tk_llequals:
2566
 
2567
			getoperand(am32==TRUE?ECX:BX);
2568
 
2569
				doalmath(0,&ofsstr);		// all shifts unsigned byte
2570
 
2571
				ClearReg(CX);
2572
 
2573
				if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP;
2574
 
2575
				op66(razr);
2576
 
2577
				op(0xD3);	op(0x20+vop+wtok.rm);  // SHL [rmword],CL
2578
 
2579
				warningreg(begs[1]);
2580
 
2581
			}
2582
 
2583
#ifdef OPTVARCONST
2584
 
2585
					initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand);
2586
 
2587
#endif
2588
 
2589
				if((unsigned int)itok.number==1){
2590
 
2591
					outseg(&wtok,2);
2592
 
2593
					outaddress(&wtok);
2594
 
2595
				else if((unsigned int)itok.number!=0){
2596
 
2597
						getintobeg(CL,&ofsstr);
2598
 
2599
						outseg(&wtok,2);
2600
 
2601
						outaddress(&wtok);
2602
 
2603
						ClearReg(CX);
2604
 
2605
					}
2606
 
2607
						op66(razr);
2608
 
2609
						op(0xC1);	op(0x20+vop+wtok.rm);  /* SHL [rmword],imm8 */
2610
 
2611
						if(cpu<2)cpu=2;
2612
 
2613
					op((unsigned int)itok.number);
2614
 
2615
			}
2616
 
2617
				if(tok!=tk_beg||(unsigned int)itok.number!=CL){
2618
 
2619
					warningreg(begs[1]);
2620
 
2621
					next=0;
2622
 
2623
				CheckAllMassiv(wbuf,razr,&wstr,&wtok);
2624
 
2625
				outseg(&wtok,2);
2626
 
2627
				outaddress(&wtok);
2628
 
2629
			break;
2630
 
2631
	}
2632
 
2633
	if(initconst==FALSE)ClearVarByNum(&wtok);
2634
 
2635
	if(next)nexttok();
2636
 
2637
	if(razr==r32&&cpu<3)cpu=3;
2638
 
2639
}
2640
 
2641
int dobytevar(int sign,int terminater)	 // byte, char
2642
 
2643
unsigned char next=1,getfromAX=0;
2644
 
2645
ITOK btok;
2646
 
2647
int retrez=0,pointr=0,hnumber=AL;
2648
 
2649
int numpointr=0;
2650
 
2651
#ifdef OPTVARCONST
2652
 
2653
int operand;
2654
 
2655
unsigned int oaddESP=addESP;
2656
 
2657
	bstr=strinf;
2658
 
2659
	btok=itok;
2660
 
2661
	bufrm=NULL;
2662
 
2663
	while(RmEqualReg(hnumber,itok.rm,itok.sib))hnumber++;
2664
 
2665
#ifdef OPTVARCONST
2666
 
2667
#endif
2668
 
2669
		case tk_assign:
2670
 
2671
				ofsstr=GetLecsem(terminater);
2672
 
2673
			if(ofsstr){
2674
 
2675
				if((retreg=CheckIDZReg(ofsstr,AX,r8))!=NOINREG){
2676
 
2677
					tok=tk_beg;
2678
 
2679
					goto regtovar;
2680
 
2681
			}
2682
 
2683
			convert_type(&sign,(int *)&rettype,&pointr);
2684
 
2685
				nexttok();
2686
 
2687
			}
2688
 
2689
			if(tok2==tk_assign){
2690
 
2691
				if(ofsstr){
2692
 
2693
					ofsstr=NULL;
2694
 
2695
				next=0;
2696
 
2697
			}
2698
 
2699
			CheckMinusNum();
2700
 
2701
				if(rettype!=tk_float&&tok==tk_number){	//проверка и суммирование чисел
2702
 
2703
						next=0;
2704
 
2705
					}
2706
 
2707
				goto labl1;
2708
 
2709
			else{
2710
 
2711
				if(tok>=tk_charvar&&tok<=tk_doublevar&&itok.npointr==0){
2712
 
2713
				}
2714
 
2715
				switch(tok){
2716
 
2717
numbertovar:
2718
 
2719
						if((initconst=Const2Var(&btok,itok.lnumber&0Xff,itok.rm))==FALSE){
2720
 
2721
							initconst=TRUE;
2722
 
2723
						}
2724
 
2725
						CheckAllMassiv(bbuf,1,&bstr,&btok);
2726
 
2727
						op(0xC6);
2728
 
2729
						outaddress(&btok);
2730
 
2731
						break;
2732
 
2733
					case tk_reg:
2734
 
2735
					case tk_beg:
2736
 
2737
						if((unsigned int)itok.number==0){
2738
 
2739
							hnumber=0;
2740
 
2741
						else{
2742
 
2743
							AddRegVar(itok.number,r8,&btok);
2744
 
2745
							CheckAllMassiv(bbuf,1,&bstr,&btok);
2746
 
2747
							op(0x88);
2748
 
2749
							outaddress(&btok);
2750
 
2751
						break;
2752
 
2753
					default:
2754
 
2755
						if(rettype==tk_char||rettype==tk_byte){
2756
 
2757
							else retrez=getintobeg(hnumber,&ofsstr);
2758
 
2759
						else if(rettype==tk_int||rettype==tk_word){
2760
 
2761
							else retrez=getintoreg(hnumber,r16,sign,&ofsstr);
2762
 
2763
						else if(rettype==tk_float){
2764
 
2765
							rettype=tk_long;
2766
 
2767
						}
2768
 
2769
							if(hnumber==0)retrez=do_e_axmath(sign,r32,&ofsstr);
2770
 
2771
						}
2772
 
2773
						next=0;
2774
 
2775
				}
2776
 
2777
			if(getfromAX){
2778
 
2779
#ifdef OPTVARCONST
2780
 
2781
#endif
2782
 
2783
				convert_returnvalue(posiblret,rettype);
2784
 
2785
				if(bbuf==NULL&&bstr.bufstr==NULL&&hnumber==0&&((btok.rm==rm_d16&&btok.sib==CODE16)||(btok.rm==rm_d32&&(btok.sib==CODE32||btok.sib==0)))){
2786
 
2787
					op(0xA2); 		// MOV [byte],AL
2788
 
2789
						AddUndefOff(2,btok.name);
2790
 
2791
					}
2792
 
2793
					else outdword(btok.number);
2794
 
2795
				else{
2796
 
2797
					outseg(&btok,2);  // MOV [rmbyte],AL
2798
 
2799
					op(btok.rm+hnumber*8);
2800
 
2801
				}
2802
 
2803
				else ClearReg(hnumber);
2804
 
2805
				AddRegVar(hnumber,r8,&btok);
2806
 
2807
			else if(vop)KillVar(btok.name);
2808
 
2809
			break;
2810
 
2811
			getoperand(am32==TRUE?EAX:BX);
2812
 
2813
				if(itok.number==1)break;
2814
 
2815
					outword(0xB0+hnumber);
2816
 
2817
				}
2818
 
2819
				if((itok.flag&f_reloc)==0){
2820
 
2821
				}
2822
 
2823
			}
2824
 
2825
			hnumber=0;
2826
 
2827
				btok.number+=addESP-oaddESP;
2828
 
2829
			}
2830
 
2831
			outseg(&btok,2);
2832
 
2833
			if(sign)op(0x28+btok.rm);
2834
 
2835
			outaddress(&btok);
2836
 
2837
			KillVar(btok.name);
2838
 
2839
		case tk_divequals:
2840
 
2841
			getoperand(am32==TRUE?EAX:BX);
2842
 
2843
				if(tok==tk_number){
2844
 
2845
#ifdef OPTVARCONST
2846
 
2847
						initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,tk_div);
2848
 
2849
 
2850
 
2851
				getintobeg(CL,&ofsstr);
2852
 
2853
 
2854
 
2855
				doalmath(sign,&ofsstr);
2856
 
2857
				if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar)){
2858
 
2859
					oaddESP=addESP;
2860
 
2861
			}
2862
 
2863
			else xorAHAH();
2864
 
2865
			warningreg(begs[3]);
2866
 
2867
			if(sign)op(0xF8+CL); // IDIV CL
2868
 
2869
			next=0;
2870
 
2871
			KillVar(btok.name);
2872
 
2873
		case tk_minusminus: vop=0x8;
2874
 
2875
#ifdef OPTVARCONST
2876
 
2877
#endif
2878
 
2879
			outseg(&btok,2);
2880
 
2881
			op(vop+btok.rm);
2882
 
2883
			KillVar(btok.name);
2884
 
2885
		case tk_xorequals: vop+=0x08;
2886
 
2887
		case tk_andequals: vop+=0x18;
2888
 
2889
		case tk_plusequals:
2890
 
2891
			getoperand(am32==TRUE?EAX:BX);
2892
 
2893
				if(tok==tk_number){
2894
 
2895
						next=0;
2896
 
2897
						tok=tk_number;
2898
 
2899
 
2900
 
2901
				doalmath(sign,&ofsstr);
2902
 
2903
				CheckAllMassiv(bbuf,1,&bstr,&btok);
2904
 
2905
				op(vop); op(btok.rm);  // ADD [anybyte],AL
2906
 
2907
				next=0;
2908
 
2909
			}
2910
 
2911
				switch(tok){
2912
 
2913
num:
2914
 
2915
						if((itok.flag&f_reloc)==0){
2916
 
2917
						}
2918
 
2919
						CheckAllMassiv(bbuf,1,&bstr,&btok);
2920
 
2921
						if(itok.number==1&&(vop==0||vop==0x28)){
2922
 
2923
							op(0xFE);
2924
 
2925
							outaddress(&btok);
2926
 
2927
						else{
2928
 
2929
							op(vop+btok.rm);
2930
 
2931
							op((unsigned int)itok.number);
2932
 
2933
						if(next==0)tok=otok;
2934
 
2935
					case tk_beg:
2936
 
2937
						initconst=CheckUpdRegToConst(itok.number,&btok,operand,r8);
2938
 
2939
						CheckAllMassiv(bbuf,1,&bstr,&btok);
2940
 
2941
						op(vop);
2942
 
2943
						outaddress(&btok);
2944
 
2945
					case tk_seg: segbyteerror(); break;
2946
 
2947
						retrez=tk_reg;
2948
 
2949
						CheckAllMassiv(bbuf,1,&bstr,&btok);
2950
 
2951
						op(vop); op(btok.rm);  /* ADD [anybyte],AL */
2952
 
2953
						next=0;
2954
 
2955
				}
2956
 
2957
			break;
2958
 
2959
			KillVar(btok.name);
2960
 
2961
			rbuf=bufrm;
2962
 
2963
 
2964
 
2965
#ifdef OPTVARCONST
2966
 
2967
#endif
2968
 
2969
					outseg(&btok,2);
2970
 
2971
					op((unsigned int)itok.number*8+btok.rm);
2972
 
2973
					ClearReg(itok.number>3?itok.number-4:itok.number);
2974
 
2975
				case tk_bytevar:
2976
 
2977
#ifdef OPTVARCONST
2978
 
2979
#endif
2980
 
2981
					else getinto_reg(otok,&btok,bbuf,&bstr,r8,hnumber);
2982
 
2983
					outseg(&itok,2);
2984
 
2985
					op(itok.rm+hnumber*8);
2986
 
2987
					KillVar(itok.name);
2988
 
2989
				default: swaperror(); break;
2990
 
2991
			break;
2992
 
2993
			vop=8;
2994
 
2995
		case tk_llequals:
2996
 
2997
			getoperand(am32==TRUE?ECX:BX);
2998
 
2999
				doalmath(0,&ofsstr);		// all shifts unsigned byte
3000
 
3001
				if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar))btok.number+=addESP-oaddESP;
3002
 
3003
				outseg(&btok,2);
3004
 
3005
				outaddress(&btok);
3006
 
3007
				ClearReg(CX);
3008
 
3009
				next=0;
3010
 
3011
			else if(tok==tk_number){
3012
 
3013
				if((itok.flag&f_reloc)==0){
3014
 
3015
				}
3016
 
3017
				if((unsigned int)itok.number==1){
3018
 
3019
					outseg(&btok,2);
3020
 
3021
					outaddress(&btok);
3022
 
3023
				else if((unsigned int)itok.number!=0){
3024
 
3025
					if(chip<2){
3026
 
3027
						outseg(&btok,2);
3028
 
3029
						outaddress(&btok);
3030
 
3031
						ClearReg(CX);
3032
 
3033
					}
3034
 
3035
						outseg(&btok,2);
3036
 
3037
						outaddress(&btok);
3038
 
3039
					}
3040
 
3041
				}
3042
 
3043
			else{
3044
 
3045
					getintobeg(CL,&ofsstr);
3046
 
3047
					ClearReg(CX);
3048
 
3049
				}
3050
 
3051
				outseg(&btok,2);
3052
 
3053
				outaddress(&btok);
3054
 
3055
			break;
3056
 
3057
	}
3058
 
3059
	if(initconst==FALSE)ClearVarByNum(&btok);
3060
 
3061
	if(next)nexttok();
3062
 
3063
	return retrez;
3064
 
3065
3066
 
3067
{
3068
 
3069
int vop=0;
3070
 
3071
	switch(gtok){
3072
 
3073
		case tk_longvar:
3074
 
3075
longvar:
3076
 
3077
			op66(razr);
3078
 
3079
			op(0x8B);
3080
 
3081
			outaddress(gstok);
3082
 
3083
			break;
3084
 
3085
			vop=8;
3086
 
3087
			i=2;
3088
 
3089
		case tk_bytevar:
3090
 
3091
			CheckAllMassiv(gbuf,i,gstr,gstok,reg1,reg2);
3092
 
3093
			op(0x8A);
3094
 
3095
			outaddress(gstok);
3096
 
3097
 
3098
 
3099
}
3100
 
3101
void  getinto_e_ax(int sign,int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr,int razr,int useAX)
3102
 
3103
unsigned int i=0;
3104
 
3105
int reg1=idxregs[0],reg2=idxregs[1];
3106
 
3107
		reg1=useAX==FALSE?EAX:idxregs[0];
3108
 
3109
	}
3110
 
3111
	switch(gtok){
3112
 
3113
			vop=gstok->bit.siz+gstok->bit.ofs;
3114
 
3115
			if(vop<=32)i=r32;
3116
 
3117
			bits2reg(AX,((unsigned int)razr>i?razr:i));
3118
 
3119
		case tk_postnumber:
3120
 
3121
			op(0xB8); /* MOV EAX,# */
3122
 
3123
			razr==r16?outword(gstok->number):outdword(gstok->number);
3124
 
3125
			break;
3126
 
3127
			CheckAllMassiv(gbuf,gstok->size,gstr,gstok,reg1,reg2);
3128
 
3129
				op66(razr);
3130
 
3131
				if(gstok->post==0)outseg(gstok,2);
3132
 
3133
				if(gstok->post!=0&&gstok->post!=UNDEF_OFSET){
3134
 
3135
						i=outptr;
3136
 
3137
						setwordpost(gstok);
3138
 
3139
					}
3140
 
3141
				}
3142
 
3143
				ClearReg(AX);
3144
 
3145
			else nexttok();
3146
 
3147
		case tk_doublevar:
3148
 
3149
		case tk_floatvar:
3150
 
3151
			if(cpu<3)cpu=3;
3152
 
3153
			op(0x50);  //push EAX
3154
 
3155
			addESP+=4;
3156
 
3157
			outseg(gstok,2);	//fld floatvar
3158
 
3159
			op(gstok->rm);
3160
 
3161
			fistp_stack();
3162
 
3163
			op(0x58);	//pop EAX
3164
 
3165
			RestoreBP();
3166
 
3167
			break;
3168
 
3169
			i=4;
3170
 
3171
		case tk_longvar:
3172
 
3173
longvar:
3174
 
3175
				op66(razr);
3176
 
3177
				op(0xA1);
3178
 
3179
				if(am32==FALSE)outword((unsigned int)gstok->number);
3180
 
3181
			}
3182
 
3183
				CheckAllMassiv(gbuf,i,gstr,gstok,reg1,reg2);
3184
 
3185
				outseg(gstok,2);
3186
 
3187
				op(gstok->rm);
3188
 
3189
			}
3190
 
3191
			break;
3192
 
3193
			vop=8;
3194
 
3195
			i=2;
3196
 
3197
			i=1;
3198
 
3199
movxx:
3200
 
3201
			op66(razr);
3202
 
3203
			op(0x0F); op(0xB6+vop+i); op(gstok->rm);
3204
 
3205
			ClearReg(AX);
3206
 
3207
		case tk_charvar:
3208
 
3209
			if(razr==r16){
3210
 
3211
					outseg(gstok,1);
3212
 
3213
					if(am32==FALSE)outword(gstok->number);
3214
 
3215
				}
3216
 
3217
					CheckAllMassiv(gbuf,1,gstr,gstok,reg1,reg2);
3218
 
3219
					op(0x8A); op(gstok->rm);
3220
 
3221
				}
3222
 
3223
				ClearReg(AX);
3224
 
3225
			}
3226
 
3227
		case tk_bytevar:
3228
 
3229
			if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){
3230
 
3231
				if(i)op66(r16);
3232
 
3233
				op(0xA0+i);
3234
 
3235
				else outdword(gstok->number);
3236
 
3237
				break;
3238
 
3239
			if((chip>=3&&(!optimizespeed))||RmEqualReg(AX,gstok->rm,gstok->sib))goto movxx;
3240
 
3241
			CheckAllMassiv(gbuf,1+i,gstr,gstok,SI,reg2);
3242
 
3243
			outseg(gstok,2);
3244
 
3245
			outaddress(gstok);
3246
 
3247
		case tk_beg:
3248
 
3249
				xorAHAH();
3250
 
3251
				break;
3252
 
3253
			if(optimizespeed&&chip>3&&chip<7){
3254
 
3255
					if(razr==r32)goto movxxr;
3256
 
3257
						op(0x88);
3258
 
3259
					}
3260
 
3261
					outword(0xFCC0);	//sar ah,7
3262
 
3263
				}
3264
 
3265
					if(razr==r32&&(gstok->number==AL||gstok->number==AH)){
3266
 
3267
/*						op(0x88);
3268
 
3269
						xorEAXEAX();
3270
 
3271
						warningreg(begs[1]);
3272
 
3273
					}
3274
 
3275
					else{
3276
 
3277
						op(0x88);
3278
 
3279
					}
3280
 
3281
				ClearReg(AX);
3282
 
3283
			}
3284
 
3285
			if(chip>2||razr==r32){
3286
 
3287
				if(sign)outword(0xBE0F);
3288
 
3289
				op(0xC0+(unsigned int)gstok->number); // MOVxX AX,beg
3290
 
3291
			else{
3292
 
3293
				op(0xC0+gstok->number*8);
3294
 
3295
				else xorAHAH();
3296
 
3297
			ClearReg(AX);
3298
 
3299
		case tk_reg:
3300
 
3301
				if(tok2==tk_openbracket){	//вызов процедуры по адресу в регистре
3302
 
3303
					nexttok();
3304
 
3305
					if(comfile==file_w32)swapparam();
3306
 
3307
					op66(r16);
3308
 
3309
					op(0xD0+reg1); 	/* CALL reg with stack params */
3310
 
3311
					FreeGlobalConst();
3312
 
3313
					clearregstat();
3314
 
3315
				}
3316
 
3317
					if(gstok->number==AX){
3318
 
3319
/*						op66(r16);
3320
 
3321
						xorEAXEAX();
3322
 
3323
						outword(0xC889);	//mov aX,cX
3324
 
3325
					}
3326
 
3327
						xorEAXEAX();
3328
 
3329
						op(0x89);
3330
 
3331
					}
3332
 
3333
				else{
3334
 
3335
					op66(r32);
3336
 
3337
					if(sign)op(0xBF);
3338
 
3339
					op(0xC0+gstok->number);
3340
 
3341
				RegToReg(AX,gstok->number,razr);
3342
 
3343
			}
3344
 
3345
			if(tok2==tk_openbracket){	//вызов процедуры по адресу в регистре
3346
 
3347
				nexttok();
3348
 
3349
				if(comfile==file_w32)swapparam();
3350
 
3351
				op66(razr);
3352
 
3353
				op(0xD0+reg1); 	/* CALL reg with stack params */
3354
 
3355
#ifdef OPTVARCONST
3356
 
3357
#endif
3358
 
3359
			}
3360
 
3361
				op66(razr);
3362
 
3363
				op(0xC0+gstok->number*8);
3364
 
3365
			}
3366
 
3367
		case tk_seg:
3368
 
3369
			op(0x8C);	//mov var,SS
3370
 
3371
			ClearReg(AX);
3372
 
3373
		case tk_string:
3374
 
3375
			op(0xB8);
3376
 
3377
				if(am32)dwordvalexpected();
3378
 
3379
			}
3380
 
3381
			ClearReg(AX);
3382
 
3383
		default: valueexpected();	break;
3384
 
3385
	if(razr==r32&&cpu<3)cpu=3;
3386
 
3387
3388
 
3389
{
3390
 
3391
unsigned long num;
3392
 
3393
		num=li[vop];
3394
 
3395
		if(val
3396
 
3397
	return vop;
3398
 
3399
3400
 
3401
{
3402
 
3403
unsigned long long num;
3404
 
3405
		num=li[vop];
3406
 
3407
		if(val
3408
 
3409
	return vop;
3410
 
3411
3412
 
3413
{
3414
 
3415
int expand=FALSE,rettype;
3416
 
3417
unsigned long holdnumber=0;
3418
 
3419
	rettype=(razr==r16?tk_reg:tk_reg32);
3420
 
3421
		if(CheckMinusNum()==FALSE){
3422
 
3423
			getoperand(am32==TRUE?EAX:BX);
3424
 
3425
	}
3426
 
3427
		if(razr==r32){
3428
 
3429
				goto contloop;	//оптимизация сложения 32-битных регистров в LEA
3430
 
3431
		}
3432
 
3433
			goto contloop;	//оптимизация сложения 32-битных регистров
3434
 
3435
	}
3436
 
3437
	otok=tok;
3438
 
3439
#ifdef OPTVARCONST
3440
 
3441
	if(tok==tk_number)calcnumber=TRUE;
3442
 
3443
	switch(tok){
3444
 
3445
			holdnumber=CalcNumber(sign);
3446
 
3447
			else i^=postnumflag;
3448
 
3449
			if(tok==tk_mult&&(optimizespeed||razr==r32)&&
3450
 
3451
		 		getoperand(am32==TRUE?EAX:BX);
3452
 
3453
				goto loopswitch;
3454
 
3455
			if(tok==tk_plus&&tok2==tk_postnumber){
3456
 
3457
				goto loopswitch;
3458
 
3459
			MovRegNum(razr,i&f_reloc,holdnumber,EAX);
3460
 
3461
			break;
3462
 
3463
			op66(razr);
3464
 
3465
			AddApiToPost(itok.number);
3466
 
3467
			break;
3468
 
3469
		case tk_undefofs:
3470
 
3471
				op66(razr);
3472
 
3473
				next=1;
3474
 
3475
			if(tok==tk_undefofs){
3476
 
3477
//				AddUndefOff(0,itok.name);	//22.11.04 20:52
3478
 
3479
			}
3480
 
3481
			tok=tk_number;
3482
 
3483
			if(otok!=tk_postnumber){
3484
 
3485
				else i^=postnumflag;
3486
 
3487
			}
3488
 
3489
				nexttok();
3490
 
3491
			}
3492
 
3493
			next=0;
3494
 
3495
			else outdword(holdnumber);
3496
 
3497
			break;
3498
 
3499
int reg1,reg2;
3500
 
3501
			reg2=am32==FALSE?idxregs[1]:ECX;
3502
 
3503
			if(itok.rm||am32==0){
3504
 
3505
				op67(itok.sib==CODE16?r16:r32);
3506
 
3507
					outseg(&itok,1);
3508
 
3509
				}
3510
 
3511
					if(itok.post==0)outseg(&itok,2);
3512
 
3513
				}
3514
 
3515
//				op(0x8D); op(itok.rm);
3516
 
3517
					if((itok.flag&f_extern)==0){
3518
 
3519
						if(am32&&itok.rm==rm_sib)outptr++;
3520
 
3521
						outptr=i;
3522
 
3523
					else setwordext(&itok.number);
3524
 
3525
ITOK oitok;
3526
 
3527
				tok=tk_number;
3528
 
3529
				oitok.number=doconstdwordmath();
3530
 
3531
				outaddress(&oitok); // LEA AX,[rm]
3532
 
3533
			}
3534
 
3535
			break;
3536
 
3537
		 	getoperand(am32==TRUE?EAX:BX);
3538
 
3539
		case tk_ID:
3540
 
3541
		case tk_proc:
3542
 
3543
		case tk_undefproc:
3544
 
3545
			if(itok.flag&f_retproc)rettype=(itok.flag&f_retproc)/256+tk_overflowflag-1;
3546
 
3547
					macros(sign!=0?(razr==r16?tk_int:tk_long):(razr==r16?tk_word:tk_dword))==0){
3548
 
3549
			}
3550
 
3551
			if(*ofsstr){
3552
 
3553
				*ofsstr=NULL;
3554
 
3555
			break;
3556
 
3557
			donew();
3558
 
3559
#ifdef OPTVARCONST
3560
 
3561
#endif
3562
 
3563
				free(*ofsstr);
3564
 
3565
			}
3566
 
3567
			break;
3568
 
3569
			SINFO wstr=strinf;
3570
 
3571
			char *wbuf=bufrm;
3572
 
3573
			strinf.bufstr=NULL;
3574
 
3575
			nexttok(); break;
3576
 
3577
contloop:
3578
 
3579
		NegReg(razr,EAX);
3580
 
3581
	}
3582
 
3583
	calcnumber=FALSE;
3584
 
3585
	if(next)RegMulNum(AX,holdnumber,razr,sign,&expand,i);
3586
 
3587
	if(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){
3588
 
3589
		rettype=(razr==r16?tk_reg:tk_reg32);
3590
 
3591
	return rettype;
3592
 
3593
3594
 
3595
{
3596
 
3597
int optnum=FALSE;
3598
 
3599
char *ofsstr=NULL;
3600
 
3601
	while(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){
3602
 
3603
		vop=0;
3604
 
3605
// !!! new
3606
 
3607
		CheckConstVar3(&tok2,&itok2,razr);
3608
 
3609
#endif
3610
 
3611
			if(Reg32ToLea2(EAX))continue;	//оптимизация сложения 32-битных регистров в LEA
3612
 
3613
		}
3614
 
3615
		if(tok2==tk_number)optnum=OptimNum();
3616
 
3617
		switch(tok){
3618
 
3619
			case tk_minus: vop+=0x08;
3620
 
3621
			case tk_or: vop+=0x08;
3622
 
3623
			  if(optnum==FALSE)getoperand();
3624
 
3625
					tok=tk_number;
3626
 
3627
				}
3628
 
3629
					case tk_number:
3630
 
3631
							if(optnumadd(itok.number,0,razr,vop))break;
3632
 
3633
					case tk_undefofs:
3634
 
3635
						op66(razr);
3636
 
3637
						if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
3638
 
3639
						else if((itok.flag&f_reloc)!=0)AddReloc();
3640
 
3641
						setzeroflag=TRUE;
3642
 
3643
					case tk_apioffset:
3644
 
3645
					  op(0x05+vop);
3646
 
3647
						setzeroflag=TRUE;
3648
 
3649
					case tk_qwordvar:
3650
 
3651
					case tk_dwordvar:
3652
 
3653
 
3654
 
3655
						if(razr==r32&&(tok==tk_intvar||tok==tk_wordvar))goto defxor;
3656
 
3657
						CheckAllMassiv(bufrm,i,&strinf);
3658
 
3659
						outseg(&itok,2);
3660
 
3661
						op(itok.rm);
3662
 
3663
						setzeroflag=TRUE;
3664
 
3665
					case tk_doublevar:
3666
 
3667
					case tk_floatvar:
3668
 
3669
						itok.number=EDX;
3670
 
3671
						goto defreg32;
3672
 
3673
					case tk_id:
3674
 
3675
					case tk_apiproc:
3676
 
3677
					case tk_declare:
3678
 
3679
						op(0x50);	//push AX
3680
 
3681
						oaddstack=addstack;
3682
 
3683
						procdo(razr==r16?(sign==0?tk_word:tk_int):(sign==0?tk_dword:tk_long));
3684
 
3685
						addESP-=razr==r16?2:4;
3686
 
3687
						op(0x58+EDX);
3688
 
3689
						warningreg(regs[razr/2-1][EDX]);
3690
 
3691
							op66(razr);
3692
 
3693
						}
3694
 
3695
					case tk_bits:
3696
 
3697
						i=itok.bit.siz+itok.bit.ofs;
3698
 
3699
						if(i<=32)vops=r32;
3700
 
3701
						bits2reg(CX,(razr
3702
 
3703
						if(vops==r64)vops=r32;
3704
 
3705
						goto defreg32;
3706
 
3707
						if(razr==r32)goto defxor;
3708
 
3709
defreg32:
3710
 
3711
						op(0x01+vop);
3712
 
3713
						setzeroflag=TRUE;
3714
 
3715
					case tk_rmnumber:
3716
 
3717
					case tk_beg:
3718
 
3719
defxor:
3720
 
3721
						op66(razr);
3722
 
3723
						op(0xC8);	/* OPT AX,CX */
3724
 
3725
						next=0;
3726
 
3727
						break;
3728
 
3729
				}
3730
 
3731
					op66(razr);
3732
 
3733
					if(oldtok==tk_plus)outword(0x00d2);	//adc dx,0
3734
 
3735
					setzeroflag=TRUE;
3736
 
3737
				break;
3738
 
3739
			case tk_mod: negflag=1-negflag; vop=1;
3740
 
3741
			case tk_div:
3742
 
3743
				else{
3744
 
3745
					optnum=FALSE;
3746
 
3747
				if(tok==tk_number){
3748
 
3749
						itok.number=-itok.number;
3750
 
3751
					}
3752
 
3753
				DivMod(vop,sign,razr,expand);
3754
 
3755
					op66(razr);
3756
 
3757
					else op(0x92);	//xchg ax,dx
3758
 
3759
				next=0;
3760
 
3761
				break;
3762
 
3763
			case tk_mult:
3764
 
3765
			  if(optnum==FALSE)getoperand();
3766
 
3767
					tok=tk_number;
3768
 
3769
				}
3770
 
3771
					itok.number=-itok.number;
3772
 
3773
				}
3774
 
3775
					case tk_number:
3776
 
3777
						break;
3778
 
3779
					case tk_longvar:
3780
 
3781
						i=2;
3782
 
3783
					case tk_wordvar:
3784
 
3785
						i+=2;
3786
 
3787
					 	op66(razr);
3788
 
3789
						op(0xF7);	//imul var
3790
 
3791
						else op(0x20+itok.rm);
3792
 
3793
						setzeroflag=FALSE;
3794
 
3795
					case tk_doublevar:
3796
 
3797
					case tk_floatvar:
3798
 
3799
					 	op66(razr);
3800
 
3801
						op(0xE8+EDX); // IMUL EDX
3802
 
3803
						warningreg(regs[1][EDX]);
3804
 
3805
					case tk_ID:
3806
 
3807
					case tk_proc:
3808
 
3809
					case tk_undefproc:
3810
 
3811
						op66(razr);
3812
 
3813
						addESP+=razr==r16?2:4;
3814
 
3815
						addstack=FALSE;
3816
 
3817
						addstack=oaddstack;
3818
 
3819
						op66(razr);
3820
 
3821
						itok.number=EDX;
3822
 
3823
						goto mulreg32;
3824
 
3825
						int vops;
3826
 
3827
						if(i<=64)vops=r64;
3828
 
3829
						if(i<=16)vops=r16;
3830
 
3831
						itok.number=CX;
3832
 
3833
						warningreg(regs[vops/2-1][ECX]);
3834
 
3835
					case tk_reg:
3836
 
3837
						if(razr==r32)goto mulreg;
3838
 
3839
mulreg32:
3840
 
3841
						op(0xF7);
3842
 
3843
						else op(0xE0+(unsigned int)itok.number);
3844
 
3845
						break;
3846
 
3847
					case tk_undefofs:
3848
 
3849
						op(0x69);
3850
 
3851
						if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
3852
 
3853
						razr==r16?outword(itok.number):outdword(itok.number);
3854
 
3855
						break;
3856
 
3857
						op66(razr);
3858
 
3859
						op(0xc0);
3860
 
3861
						setzeroflag=FALSE;
3862
 
3863
					case tk_seg:
3864
 
3865
					case tk_beg:
3866
 
3867
					case tk_rmnumber:
3868
 
3869
						i=EDX;
3870
 
3871
						getintoreg_32(i,razr,sign,&ofsstr,FALSE);
3872
 
3873
						op(0xF7);
3874
 
3875
						else op(0xE0+i); /* MUL i */
3876
 
3877
						setzeroflag=FALSE;
3878
 
3879
						if(i!=EDX)warningreg(regs[razr/2-1][i]);
3880
 
3881
					default: valueexpected();	break;
3882
 
3883
				break;
3884
 
3885
			case tk_andminus: vop+=0x18;
3886
 
3887
			  getoperand();
3888
 
3889
					itok.number=-itok.number;
3890
 
3891
					op(0x05+vop);
3892
 
3893
					razr==r16?outword((unsigned int)itok.number):outdword(itok.number);
3894
 
3895
				else{
3896
 
3897
					NegReg(razr,ECX);
3898
 
3899
					op(0x01+vop);	/* opt AX,CX */
3900
 
3901
					warningreg(regs[razr/2-1][1]);
3902
 
3903
				}
3904
 
3905
				break;
3906
 
3907
			  getoperand();
3908
 
3909
					if(expand==TRUE){
3910
 
3911
						 	op66(razr);
3912
 
3913
							outword(0xC2a4);	//SHLD DX,AX,num
3914
 
3915
						}
3916
 
3917
							if((unsigned int)itok.number==1)outdword(0xd213c001);	//ADD AX,AX ADC DX,DX
3918
 
3919
								getintobeg(CL,&ofsstr);
3920
 
3921
								outword(0xfae2);  //LOOP -6
3922
 
3923
								next=0;
3924
 
3925
							break;
3926
 
3927
					}
3928
 
3929
					setzeroflag=TRUE;
3930
 
3931
				else goto llminus;
3932
 
3933
			case tk_llminus:
3934
 
3935
llminus:
3936
 
3937
					getintobeg(CL,&ofsstr);
3938
 
3939
				}
3940
 
3941
				next=0;
3942
 
3943
					if(chip>2||razr==r32){
3944
 
3945
						op(0x0f);
3946
 
3947
					}
3948
 
3949
						outdword(0xd213c001);	//ADD AX,AX ADC DX,DX
3950
 
3951
						break;
3952
 
3953
				op66(razr);
3954
 
3955
				setzeroflag=TRUE;
3956
 
3957
			case tk_rr:
3958
 
3959
				getoperand();
3960
 
3961
					if(tok==tk_number){
3962
 
3963
							op66(razr);
3964
 
3965
							op66(razr);
3966
 
3967
							setzeroflag=TRUE;
3968
 
3969
						else if((unsigned int)itok.number!=0){
3970
 
3971
						 		op66(razr);
3972
 
3973
								outword(0xd0ac);	//shrd ax,dx,num
3974
 
3975
						 		op66(razr);
3976
 
3977
								op(itok.number);
3978
 
3979
							}
3980
 
3981
								next=0;
3982
 
3983
								warningreg(begs[1]);
3984
 
3985
								outdword(0xfae2d8d1);  //rcr ax,1 LOOP -6
3986
 
3987
							}
3988
 
3989
					}
3990
 
3991
				}
3992
 
3993
					RshiftReg(razr,EAX,vop);
3994
 
3995
					next=0;
3996
 
3997
				break;
3998
 
3999
				if(sign)vop=0x10;
4000
 
4001
rrminus:
4002
 
4003
					getintobeg(CL,&ofsstr);
4004
 
4005
				}
4006
 
4007
				if(expand==TRUE){
4008
 
4009
			 			op66(razr);
4010
 
4011
						outword(0xd0ad);	//shrd ax,dx,cl
4012
 
4013
						op(0xd3); op(0xea+vop);//s?r dx,num
4014
 
4015
					}
4016
 
4017
						op(0xd1); op(0xea+vop);//s?r dx,1
4018
 
4019
						setzeroflag=FALSE;
4020
 
4021
				}
4022
 
4023
		 			op66(razr);
4024
 
4025
					setzeroflag=TRUE;
4026
 
4027
				next=0;
4028
 
4029
			default: operatorexpected(); break;
4030
 
4031
		calcnumber=FALSE;
4032
 
4033
		if(negflag){
4034
 
4035
			setzeroflag=TRUE;
4036
 
4037
		}
4038
 
4039
	}
4040
 
4041
	ClearReg(EAX);
4042
 
4043
	if(razr==r32&&cpu<3)cpu=3;
4044
 
4045
4046
 
4047
{
4048
 
4049
	switch(gtok){
4050
 
4051
			int razr;
4052
 
4053
			if(i<=64)razr=r64;
4054
 
4055
			if(i<=16)razr=r16;
4056
 
4057
			bits2reg(AL,razr);
4058
 
4059
		case tk_number:
4060
 
4061
			op(gstok->number);
4062
 
4063
			break;
4064
 
4065
			CheckAllMassiv(gbuf,gstok->size,gstr,gstok);
4066
 
4067
			op67(gstok->sib==CODE16?r16:r32);
4068
 
4069
			op(0x8D);	/* LEA AX,[rm] */
4070
 
4071
			if(gstok->post!=0&&gstok->post!=UNDEF_OFSET){
4072
 
4073
					i=outptr;
4074
 
4075
					setwordpost(gstok);
4076
 
4077
				}
4078
 
4079
			}
4080
 
4081
			ClearReg(AL);
4082
 
4083
		case tk_postnumber:
4084
 
4085
			op(0xB8);	/* MOV AX,# */
4086
 
4087
			outword(gstok->number);
4088
 
4089
			break;
4090
 
4091
			if(cpu<3)cpu=3;
4092
 
4093
			op66(r32);
4094
 
4095
			if(ESPloc&&am32&&gstok->segm==SS)gstok->number+=4;
4096
 
4097
			CheckAllMassiv(gbuf,4,gstr,gstok);
4098
 
4099
			op(0xd9);
4100
 
4101
			outaddress(gstok);
4102
 
4103
			op66(r32);
4104
 
4105
			addESP-=4;
4106
 
4107
			ClearReg(AL);
4108
 
4109
		case tk_qwordvar:
4110
 
4111
		case tk_longvar:
4112
 
4113
			i+=2;
4114
 
4115
		case tk_wordvar:
4116
 
4117
		case tk_bytevar:
4118
 
4119
			i++;
4120
 
4121
				outseg(gstok,1);
4122
 
4123
				if(gstok->post==UNDEF_OFSET)AddUndefOff(2,gstok->name);
4124
 
4125
				else outdword(gstok->number);
4126
 
4127
			else{
4128
 
4129
				outseg(gstok,2);
4130
 
4131
				op(gstok->rm);
4132
 
4133
			}
4134
 
4135
			break;
4136
 
4137
			if(gstok->number>BX){
4138
 
4139
	 			if(gstok->number!=AX)op66(r32);
4140
 
4141
			goto beg1;
4142
 
4143
			if(gstok->number>BX){
4144
 
4145
	 			if(gstok->number!=AX)op66(r16);
4146
 
4147
		case tk_beg:
4148
 
4149
			if(gstok->number!=AL){
4150
 
4151
				op(0xC0+gstok->number*8);
4152
 
4153
			ClearReg(AL);
4154
 
4155
		case tk_seg:
4156
 
4157
			op(0x8C); op(0xC0+gstok->number*8); break;
4158
 
4159
		default: bytevalexpected(0); break;
4160
 
4161
}
4162
 
4163
int doalmath(int sign,char **ofsstr)
4164
 
4165
int negflag=0,i=0;
4166
 
4167
	if(tok==tk_minus){
4168
 
4169
			negflag=1;
4170
 
4171
		}
4172
 
4173
#ifdef OPTVARCONST
4174
 
4175
		if(CheckConstVar(&itok)){
4176
 
4177
			calcnumber=TRUE;
4178
 
4179
	}
4180
 
4181
	switch(tok){
4182
 
4183
			op(0xB0);	//mov AL,num
4184
 
4185
			op(i);
4186
 
4187
			break;
4188
 
4189
		 	getoperand(am32==TRUE?EAX:BX);
4190
 
4191
		case tk_ID:
4192
 
4193
		case tk_proc:
4194
 
4195
		case tk_undefproc:
4196
 
4197
			if(itok.flag&f_retproc)rettype=(itok.flag&f_retproc)/256+tk_overflowflag-1;
4198
 
4199
			nexttok();
4200
 
4201
				free(*ofsstr);
4202
 
4203
			}
4204
 
4205
		default:
4206
 
4207
			strinf.bufstr=NULL;
4208
 
4209
			char *bbuf;
4210
 
4211
			bbuf=bufrm;
4212
 
4213
			getintoal(tok,&btok,bbuf,&bstr); nexttok(); break;
4214
 
4215
#ifdef OPTVARCONST
4216
 
4217
#endif
4218
 
4219
		if(optimizespeed&&(chip==5||chip==6))outdword(0xC0FEFF34);	//xor AL,-1 AL++
4220
 
4221
		setzeroflag=TRUE;
4222
 
4223
	if(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){
4224
 
4225
		rettype=tk_beg;
4226
 
4227
	return rettype;
4228
 
4229
4230
 
4231
{
4232
 
4233
int expand=FALSE,optnum=FALSE;
4234
 
4235
char *ofsstr=NULL;
4236
 
4237
		vop=0;
4238
 
4239
		next=1;
4240
 
4241
		if(tok2>=tk_charvar&&tok2<=tk_doublevar&&itok2.npointr==0){
4242
 
4243
				tok2=tk_number;
4244
 
4245
			}
4246
 
4247
#endif
4248
 
4249
		int oldtok=tok;
4250
 
4251
			case tk_xor: vop+=0x08;
4252
 
4253
			case tk_and: vop+=0x18;
4254
 
4255
			case tk_plus:
4256
 
4257
				else{
4258
 
4259
					optnum=FALSE;
4260
 
4261
				switch(tok){
4262
 
4263
						if(itok.number==0&&oldtok!=tk_and)break;
4264
 
4265
					  op(0x04+vop);
4266
 
4267
						break;
4268
 
4269
						CheckAllMassiv(bufrm,itok.size,&strinf);
4270
 
4271
						op67(itok.sib==CODE16?r16:r32);
4272
 
4273
						op(0x8D); /* LEA CX,[rm] */
4274
 
4275
						if(itok.post!=0&&itok.post!=UNDEF_OFSET){
4276
 
4277
								unsigned int ooutptr=outptr;
4278
 
4279
								setwordpost(&itok);
4280
 
4281
							}
4282
 
4283
						}
4284
 
4285
						op(vop); /* OPT AL,CL */
4286
 
4287
						warningreg(regs[0][1]);
4288
 
4289
					case tk_postnumber:
4290
 
4291
						op(0x05+vop); /* OPT AX,# */
4292
 
4293
						outword((unsigned int)itok.number);
4294
 
4295
					case tk_qwordvar:
4296
 
4297
					case tk_longvar:
4298
 
4299
						i+=2;
4300
 
4301
					case tk_wordvar:
4302
 
4303
					case tk_charvar:
4304
 
4305
						i++;
4306
 
4307
						outseg(&itok,2);
4308
 
4309
						outaddress(&itok);
4310
 
4311
					case tk_ID:
4312
 
4313
					case tk_proc:
4314
 
4315
					case tk_undefproc:
4316
 
4317
						op66(r16);
4318
 
4319
						addESP+=2;
4320
 
4321
						oaddstack=addstack;
4322
 
4323
						procdo(sign!=0?tk_char:tk_byte);
4324
 
4325
						addESP-=2;
4326
 
4327
						op(0x58+CX);
4328
 
4329
						warningreg(regs[0][CX]);
4330
 
4331
							op66(r16);
4332
 
4333
						}
4334
 
4335
					case tk_bits:
4336
 
4337
						i=itok.bit.siz+itok.bit.ofs;
4338
 
4339
						if(i<=32)razr=r32;
4340
 
4341
						if(i<=8)razr=r8;
4342
 
4343
						itok.number=CL;
4344
 
4345
				 		warningreg(razr==r8?begs[1]:(regs[razr/2-1][1]));
4346
 
4347
					case tk_doublevar:
4348
 
4349
					case tk_floatvar:
4350
 
4351
						itok.number=0;
4352
 
4353
defbeg:
4354
 
4355
						op(0xC0+(unsigned int)itok.number*8);
4356
 
4357
					case tk_reg32:
4358
 
4359
						if((unsigned int)itok.number>BX){
4360
 
4361
							op(0x89);	/* MOV CX,reg */
4362
 
4363
						op(0xC1+(unsigned int)itok.number*8); /* MOV instr */
4364
 
4365
						}
4366
 
4367
					default: valueexpected(); break;
4368
 
4369
				setzeroflag=TRUE;
4370
 
4371
					if(oldtok==tk_plus){
4372
 
4373
						op(0);
4374
 
4375
					else if(oldtok==tk_minus){
4376
 
4377
						op(0);
4378
 
4379
					setzeroflag=FALSE;
4380
 
4381
				break;
4382
 
4383
			case tk_mod: negflag=1-negflag; vop=1;
4384
 
4385
			case tk_div:
4386
 
4387
				else{
4388
 
4389
					optnum=FALSE;
4390
 
4391
				if(tok==tk_number){
4392
 
4393
						itok.number=-itok.number;
4394
 
4395
					}
4396
 
4397
					if(vop){	//%
4398
 
4399
						if(caselong(itok.number)!=NUMNUM){
4400
 
4401
							op((unsigned int)itok.number-1);
4402
 
4403
						}
4404
 
4405
							if(expand==FALSE){
4406
 
4407
								else xorAHAH();
4408
 
4409
							op(0xB1); op((unsigned int)itok.number); /* MOV CL,# */
4410
 
4411
							else outword(0xF1F6); /* DIV CL */
4412
 
4413
							setzeroflag=FALSE;
4414
 
4415
							break;
4416
 
4417
					}
4418
 
4419
						switch((unsigned int)itok.number){
4420
 
4421
								DevideZero();
4422
 
4423
							case 1:	break;
4424
 
4425
								op(0xd0+expand);
4426
 
4427
								else op(0xE8);// SHR AL,1
4428
 
4429
								break;
4430
 
4431
								vop=caselong(itok.number);
4432
 
4433
									if(chip<2){
4434
 
4435
										op(0xd2+expand);
4436
 
4437
										else op(0xE8); // SHR AL,CL
4438
 
4439
									}
4440
 
4441
										op(0xc0+expand);
4442
 
4443
										else op(0xE8); /* SHR AL,num */
4444
 
4445
										if(cpu<2)cpu=2;
4446
 
4447
									setzeroflag=TRUE;
4448
 
4449
								else{
4450
 
4451
										if(optimizespeed&&(itok.flag&f_reloc)==0&&sign==0){	//for signed needed new algoritm
4452
 
4453
											itok.number=256/(unsigned int)itok.number+1;
4454
 
4455
												xorAHAH();
4456
 
4457
												outword(0xC06B);	//imul AX,num
4458
 
4459
												warningreg(regs[0][2]);
4460
 
4461
											else{
4462
 
4463
												op(itok.number);
4464
 
4465
												warningreg(begs[2]);
4466
 
4467
											outword(0xE088);	//mov AL.AH
4468
 
4469
											break;
4470
 
4471
										if(sign)cbw();
4472
 
4473
									}
4474
 
4475
									op((unsigned int)itok.number);
4476
 
4477
									else outword(0xF1F6); /* DIV CL */
4478
 
4479
						 			warningreg(begs[1]);
4480
 
4481
						}
4482
 
4483
				}
4484
 
4485
					case tk_doublevar:
4486
 
4487
					if(tok==tk_floatvar){
4488
 
4489
						itok.number=ECX;
4490
 
4491
						sign=1;
4492
 
4493
					if(expand==FALSE){
4494
 
4495
						else xorAHAH();
4496
 
4497
					switch(tok){
4498
 
4499
						case tk_postnumber:
4500
 
4501
							if(sign)outword(0xF9F6);  // IDIV CL
4502
 
4503
							setzeroflag=FALSE;
4504
 
4505
							break;
4506
 
4507
							i=4;
4508
 
4509
						case tk_dwordvar:
4510
 
4511
						case tk_intvar:
4512
 
4513
							i++;
4514
 
4515
						case tk_bytevar:
4516
 
4517
							CheckAllMassiv(bufrm,i,&strinf);
4518
 
4519
							op(0xF6);
4520
 
4521
							else op(0x30+itok.rm);
4522
 
4523
							setzeroflag=FALSE;
4524
 
4525
						case tk_bits:
4526
 
4527
							i=itok.bit.siz+itok.bit.ofs;
4528
 
4529
							if(i<=32)razr=r32;
4530
 
4531
							if(i<=8)razr=r8;
4532
 
4533
							itok.number=CL;
4534
 
4535
					 		warningreg(razr==r8?begs[1]:(regs[razr/2-1][1]));
4536
 
4537
						case tk_ID:
4538
 
4539
						case tk_proc:
4540
 
4541
						case tk_undefproc:
4542
 
4543
							op66(r16);
4544
 
4545
							addESP+=2;
4546
 
4547
							oaddstack=addstack;
4548
 
4549
							procdo(sign!=0?tk_char:tk_byte);
4550
 
4551
							addESP-=2;
4552
 
4553
							op(0x58+CX);
4554
 
4555
							warningreg(regs[0][CX]);
4556
 
4557
							op(0x90+CX);	//xchg ax,cx
4558
 
4559
defdiv:
4560
 
4561
							if(sign)op(0xF8+(unsigned int)itok.number);
4562
 
4563
							setzeroflag=FALSE;
4564
 
4565
						case tk_reg32:
4566
 
4567
							if((unsigned int)itok.number>BX){
4568
 
4569
								op(0x89);  /* MOV CX,reg */
4570
 
4571
								op(0xC1+(unsigned int)itok.number*8); /* MOV instr */
4572
 
4573
							}
4574
 
4575
						default: valueexpected();	break;
4576
 
4577
					if(vop)outword(0xE088);// MOV AL,AH
4578
 
4579
				expand=FALSE;
4580
 
4581
			case tk_multminus: negflag=1;
4582
 
4583
				expand=expandvar();
4584
 
4585
				else{
4586
 
4587
					optnum=FALSE;
4588
 
4589
				switch(tok){
4590
 
4591
						if(negflag){
4592
 
4593
							negflag=0;
4594
 
4595
						itok.number&=255;
4596
 
4597
							case 0: /* AL * 0 = MOV AL,0 */
4598
 
4599
							case 1:
4600
 
4601
								setzeroflag=FALSE;
4602
 
4603
							case 2:
4604
 
4605
									if(sign)cbw();
4606
 
4607
								}
4608
 
4609
								setzeroflag=TRUE;
4610
 
4611
							default:
4612
 
4613
								if(vop!=NUMNUM){
4614
 
4615
										if(expand==TRUE){
4616
 
4617
											if(sign)cbw();
4618
 
4619
										}
4620
 
4621
										outword(0xE0D2+expand);// SHL AL,CL
4622
 
4623
									}
4624
 
4625
										if(expand==TRUE){
4626
 
4627
											if(sign)cbw();
4628
 
4629
									 		op66(r16);
4630
 
4631
										outword(0xe0c0+expand);	//SHL AX/L,num
4632
 
4633
										if(cpu<1)cpu=1;
4634
 
4635
									setzeroflag=TRUE;
4636
 
4637
								else if(expand==FALSE&&optimizespeed!=FALSE&&
4638
 
4639
								else{
4640
 
4641
									op(0xB1);  /* MOV CL,# */
4642
 
4643
									if(sign)outword(0xE9F6);// IMUL CL
4644
 
4645
									setzeroflag=FALSE;
4646
 
4647
								}
4648
 
4649
						break;
4650
 
4651
					case tk_postnumber:
4652
 
4653
						if(sign)outword(0xE9F6); // IMUL CL
4654
 
4655
						setzeroflag=FALSE;
4656
 
4657
						break;
4658
 
4659
						i=4;
4660
 
4661
						Float2reg32(ECX,i);
4662
 
4663
						outword(0xE9F6); // IMUL CL
4664
 
4665
				 		warningreg(begs[1]);
4666
 
4667
					case tk_qwordvar:
4668
 
4669
					case tk_longvar:
4670
 
4671
						i+=2;
4672
 
4673
					case tk_wordvar:
4674
 
4675
					case tk_charvar:
4676
 
4677
						i++;
4678
 
4679
						outseg(&itok,2);
4680
 
4681
						if(sign)op(0x28+itok.rm);
4682
 
4683
						outaddress(&itok);
4684
 
4685
						break;
4686
 
4687
						int razr;
4688
 
4689
						if(i<=64)razr=r64;
4690
 
4691
						if(i<=16)razr=r16;
4692
 
4693
						bits2reg(CL,razr);
4694
 
4695
						if(razr==r64)razr=r32;
4696
 
4697
						goto defmul;
4698
 
4699
					case tk_id:
4700
 
4701
					case tk_apiproc:
4702
 
4703
					case tk_declare:
4704
 
4705
						op(0x50);	//push AX
4706
 
4707
unsigned char oaddstack;
4708
 
4709
						addstack=FALSE;
4710
 
4711
						addstack=oaddstack;
4712
 
4713
						op66(r16);
4714
 
4715
						itok.number=DX;
4716
 
4717
					case tk_beg:
4718
 
4719
						op(0xF6);
4720
 
4721
						else op(0xE0+(unsigned int)itok.number);
4722
 
4723
						break;
4724
 
4725
					case tk_reg:
4726
 
4727
					 		op66(r16);
4728
 
4729
					 		warningreg(regs[0][1]);
4730
 
4731
							itok.number=CL;
4732
 
4733
						goto defmul;
4734
 
4735
				}
4736
 
4737
			case tk_xorminus: vop+=0x10;
4738
 
4739
			case tk_orminus: vop+=0x08;
4740
 
4741
				if(tok==tk_number){
4742
 
4743
					op(0x04+vop);
4744
 
4745
				}
4746
 
4747
					getintobeg(CL,&ofsstr);
4748
 
4749
						op(0x80);
4750
 
4751
					}
4752
 
4753
					op(0x00+vop);
4754
 
4755
			 		warningreg(begs[1]);
4756
 
4757
				}
4758
 
4759
				break;
4760
 
4761
				vop=8;
4762
 
4763
			case tk_ll:
4764
 
4765
				if(tok==tk_number){
4766
 
4767
						if(expand==TRUE)op66(r16);
4768
 
4769
					}
4770
 
4771
						if(chip<2) goto llminus;
4772
 
4773
							if(expand==TRUE)op66(r16);
4774
 
4775
							op((unsigned int)itok.number);
4776
 
4777
						}
4778
 
4779
					setzeroflag=TRUE;
4780
 
4781
				else goto llminus;
4782
 
4783
			case tk_rrminus:
4784
 
4785
				if(sign)vop+=0x10;
4786
 
4787
				tok=tk_minus; 	// need 286+ opt some time
4788
 
4789
				if(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==1)){
4790
 
4791
			 		warningreg(begs[1]);
4792
 
4793
				else getoperand();
4794
 
4795
				op(0xD2+expand); op(0xE0+vop);
4796
 
4797
				next=0;
4798
 
4799
			default: operatorexpected(); break;
4800
 
4801
		if(negflag){
4802
 
4803
			else outword(0xD8F6);// NEG AL
4804
 
4805
			setzeroflag=TRUE;
4806
 
4807
		if(next)nexttok();
4808
 
4809
	}
4810
 
4811
	calcnumber=FALSE;
4812
 
4813
	if(tok==tk_eof)unexpectedeof();
4814
 
4815
4816
 
4817
4818
 
4819
{
4820
 
4821
int vop=0,sign=0;
4822
 
4823
int reg1=idxregs[0],reg2=idxregs[1];
4824
 
4825
int rettype=tk_reg;
4826
 
4827
int numpointr=0;
4828
 
4829
	if(reg==reg1){
4830
 
4831
		reg2=idxregs[2];
4832
 
4833
	if(reg==reg2)reg2=idxregs[2];
4834
 
4835
	rrettype=razr==r16?tk_word:tk_dword;
4836
 
4837
	switch(tok){
4838
 
4839
			if(am32)idxregs[4]=reg;
4840
 
4841
				ofsstr=GetLecsem(terminater);
4842
 
4843
			else{
4844
 
4845
				switch(tok){
4846
 
4847
						i=r8;
4848
 
4849
					case tk_reg:
4850
 
4851
						break;
4852
 
4853
						i=r32;
4854
 
4855
				}
4856
 
4857
				waralreadinitreg(regs[razr/4][itok.number],regs[razr/4][reg]);
4858
 
4859
				break;
4860
 
4861
			if(ofsstr){
4862
 
4863
				if((retreg=CheckIDZReg(ofsstr,reg,razr))!=NOINREG){
4864
 
4865
					if(razr==r16)tok=tk_reg;
4866
 
4867
					itok.number=retreg==SKIPREG?reg:retreg;
4868
 
4869
				}
4870
 
4871
			nexttok();
4872
 
4873
			if(rrettype==tk_float||rrettype==tk_double){
4874
 
4875
				doeaxfloatmath(tk_reg32,reg,rrettype==tk_float?0:4);
4876
 
4877
				if(ofsstr){
4878
 
4879
					free(ofsstr);
4880
 
4881
				break;
4882
 
4883
			while(tok==tk_mult){
4884
 
4885
				numpointr++;
4886
 
4887
			if(numpointr>itok.npointr)unuseableinput();
4888
 
4889
				int hnumber=MultiAssign(razr,USEALLREG,numpointr);
4890
 
4891
				if(ofsstr){
4892
 
4893
					ofsstr=NULL;
4894
 
4895
				if(reg!=hnumber){
4896
 
4897
					op(0x89);
4898
 
4899
				}
4900
 
4901
/*				if(ofsstr){
4902
 
4903
					free(ofsstr);
4904
 
4905
				if(am32)idxregs[4]=255;
4906
 
4907
			}
4908
 
4909
			if(tok==tk_pointer)cpointr(am32==TRUE?reg:BX,numpointr);
4910
 
4911
				if(tok==tk_new)donew();
4912
 
4913
					dodelete();
4914
 
4915
				}
4916
 
4917
				if(reg!=AX){
4918
 
4919
				}
4920
 
4921
#ifdef OPTVARCONST
4922
 
4923
#endif
4924
 
4925
					free(ofsstr);
4926
 
4927
				}
4928
 
4929
			}
4930
 
4931
 
4932
 
4933
				if(rrettype==tk_char||rrettype==tk_byte)rettype=doalmath(sign,&ofsstr);
4934
 
4935
				else rettype=do_e_axmath(sign,r32,&ofsstr);
4936
 
4937
			}
4938
 
4939
				if(rrettype==tk_char||rrettype==tk_byte&®<=BX){
4940
 
4941
					if(itok.type!=tp_stopper&&tok!=tk_eof){
4942
 
4943
						rettype=tk_beg;
4944
 
4945
					op66(razr);
4946
 
4947
					if(!sign)op(0xB6);
4948
 
4949
					op(0xC0+reg*9);
4950
 
4951
				else{
4952
 
4953
					else next=r32;
4954
 
4955
					if(next==r16&&razr==r32){
4956
 
4957
 
4958
 
4959
						else op(0xBF);
4960
 
4961
					}
4962
 
4963
			}
4964
 
4965
			if(ofsstr){
4966
 
4967
				free(ofsstr);
4968
 
4969
			break;
4970
 
4971
			ClearReg(reg);
4972
 
4973
		case tk_minusminus: op66(razr); op(0x48+reg);
4974
 
4975
			break;
4976
 
4977
		case tk_pascal:
4978
 
4979
		case tk_stdcall:
4980
 
4981
			nexttok();
4982
 
4983
				expected('(');
4984
 
4985
			}
4986
 
4987
			param[0]=0;
4988
 
4989
			switch ( vop ) {
4990
 
4991
				case tk_stdcall:
4992
 
4993
					break;
4994
 
4995
					doparams();
4996
 
4997
				case tk_fastcall:
4998
 
4999
					break;
5000
 
5001
					if(comfile==file_w32)swapparam();
5002
 
5003
			}
5004
 
5005
			op66(razr);
5006
 
5007
			op(0xD0+reg); 	/* CALL reg with stack params */
5008
 
5009
			clearregstat();
5010
 
5011
			FreeGlobalConst();
5012
 
5013
			break;
5014
 
5015
			getoperand(reg==BX?SI:BX);
5016
 
5017
				case tk_qwordvar:
5018
 
5019
				case tk_dwordvar:
5020
 
5021
					i=4;
5022
 
5023
			 	case tk_intvar:
5024
 
5025
					i=2;
5026
 
5027
swapint:
5028
 
5029
					CheckAllMassiv(bufrm,i,&strinf,&itok,reg1,reg2);
5030
 
5031
			 		outseg(&itok,2);
5032
 
5033
					op(reg*8+itok.rm);
5034
 
5035
					break;
5036
 
5037
					if(razr==r16)swaperror();
5038
 
5039
				case tk_reg:
5040
 
5041
swapreg:
5042
 
5043
						if(RegSwapReg(reg,itok.number,razr)==NOINREG){;
5044
 
5045
							if(reg==AX)op(0x90+(unsigned int)itok.number);
5046
 
5047
							else{
5048
 
5049
								op(0xC0+(unsigned int)itok.number+reg*8);
5050
 
5051
						}
5052
 
5053
					}
5054
 
5055
				default: swaperror(); break;
5056
 
5057
			break;
5058
 
5059
		case tk_minusequals: vop+=0x08;
5060
 
5061
		case tk_orequals: vop+=0x08;
5062
 
5063
			ClearReg(reg);
5064
 
5065
				if(RegEqualToLea(reg)){
5066
 
5067
					break;
5068
 
5069
			}
5070
 
5071
				inptr2--;
5072
 
5073
				if(tok==tk_plusequals)tok=tk_plus;
5074
 
5075
				if(reg==EAX)do_e_axmath2(0,razr,0);
5076
 
5077
				next=0;
5078
 
5079
			}
5080
 
5081
			if(itok2.type==tp_opperand&&tok!=tk_number&&tok!=tk_undefofs&&tok!=tk_postnumber)goto defadd;
5082
 
5083
			idrec *rrec;
5084
 
5085
			i=tok;
5086
 
5087
				case tk_postnumber:
5088
 
5089
					ii=itok.number;
5090
 
5091
					opost=itok.post;
5092
 
5093
					strcpy(uname,itok.name);
5094
 
5095
					tok=tk_number;
5096
 
5097
					ii=doconstdwordmath();
5098
 
5099
					if(itok.type==tp_opperand){
5100
 
5101
							sign=ECX;
5102
 
5103
							warningreg(regs[razr/2-1][sign]);
5104
 
5105
						if(i==tk_postnumber||i==tk_undefofs){
5106
 
5107
							op(0xB8+reg);	// MOV reg,#
5108
 
5109
							else{
5110
 
5111
								if(i==tk_undefofs)AddUndefOff(2,uname);
5112
 
5113
							razr==r16?outword(ii):outdword(ii);
5114
 
5115
						else MovRegNum(razr,postnumflag&f_reloc,ii,sign);
5116
 
5117
						else doregmath_32(sign,razr,0,&ofsstr);
5118
 
5119
						goto addreg;
5120
 
5121
					if((postnumflag&f_reloc)==0&&i!=tk_undefofs&&i!=tk_postnumber&&optnumadd(ii,reg,razr,vop))break;
5122
 
5123
					op66(razr);
5124
 
5125
					else{
5126
 
5127
						op(0xC0+vop+reg);
5128
 
5129
					itok.rec=rrec;
5130
 
5131
					if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii);
5132
 
5133
						if((postnumflag&f_reloc)!=0)AddReloc();
5134
 
5135
					}
5136
 
5137
					break;
5138
 
5139
				case tk_longvar:
5140
 
5141
					i=4;
5142
 
5143
				case tk_intvar:
5144
 
5145
					i=2;
5146
 
5147
wordadd:
5148
 
5149
					op66(razr);
5150
 
5151
					op(0x03+vop);
5152
 
5153
					outaddress(&itok);
5154
 
5155
				case tk_reg:
5156
 
5157
				case tk_reg32:
5158
 
5159
					op66(razr);
5160
 
5161
					op(0xC0+reg+(unsigned int)itok.number*8);
5162
 
5163
				case tk_ID:
5164
 
5165
				case tk_proc:
5166
 
5167
				case tk_undefproc:
5168
 
5169
unsigned char oaddstack;
5170
 
5171
						op66(razr);
5172
 
5173
						addESP+=razr==r16?2:4;
5174
 
5175
						oaddstack=addstack;
5176
 
5177
					}
5178
 
5179
					if(itok2.type==tp_opperand){
5180
 
5181
						do_e_axmath2(0,razr,0);
5182
 
5183
					}
5184
 
5185
						addstack=oaddstack;
5186
 
5187
						op66(razr);
5188
 
5189
						if(vop>0x20){
5190
 
5191
							op(0x90+EDX);	//xchg ax,dx
5192
 
5193
						op66(razr);
5194
 
5195
						op(0xc0+EDX*8);	//add ax,dx
5196
 
5197
					else{
5198
 
5199
						op(0x01+vop);
5200
 
5201
					}
5202
 
5203
				case tk_seg:
5204
 
5205
				case tk_bytevar:
5206
 
5207
				case tk_beg:
5208
 
5209
					if(reg==AX){
5210
 
5211
						doregmath_32(ECX,razr,sign,&ofsstr);
5212
 
5213
					}
5214
 
5215
						do_e_axmath(0,razr,&ofsstr);
5216
 
5217
					}
5218
 
5219
					op66(razr);// OPT reg32,ECX
5220
 
5221
					op(0xC0+reg+sign*8);
5222
 
5223
					break;
5224
 
5225
			}
5226
 
5227
		case tk_rrequals: vop+=0x08;
5228
 
5229
			ClearReg(reg);
5230
 
5231
			CheckMinusNum();
5232
 
5233
				ii=doconstlongmath();
5234
 
5235
				if(itok.type==tp_opperand){
5236
 
5237
					op(0xB0+CL); op(ii);	//mov CL,num
5238
 
5239
					warningreg(begs[1]);
5240
 
5241
					goto shiftcl;
5242
 
5243
				if(ii==1){
5244
 
5245
					op(0xD1); op(0xE0+reg+vop);
5246
 
5247
				else if(ii!=0){
5248
 
5249
						op(0xB0+CL); op(ii);	//mov CL,num
5250
 
5251
						ConstToReg(ii,CL,r8);
5252
 
5253
					}
5254
 
5255
						op66(razr);
5256
 
5257
						op(ii);
5258
 
5259
					}
5260
 
5261
			}
5262
 
5263
				if(!(itok2.type==tp_stopper&&(tok==tk_beg||tok==reg||tok==tk_reg32)&&itok.number==CL)){
5264
 
5265
					dobegmath(CL);
5266
 
5267
					ClearReg(CL);
5268
 
5269
				}
5270
 
5271
				op66(razr);
5272
 
5273
			}
5274
 
5275
			break;
5276
 
5277
			ClearReg(reg);
5278
 
5279
 
5280
 
5281
				ii=doconstlongmath();
5282
 
5283
				if(itok.type==tp_opperand){
5284
 
5285
					MovRegNum(razr,postnumflag&f_reloc,ii,sign);
5286
 
5287
					else doregmath_32(ECX,razr,0,&ofsstr);
5288
 
5289
					goto mulreg;
5290
 
5291
				i=0;
5292
 
5293
			}
5294
 
5295
				if(itok2.type==tp_stopper)next=(unsigned char)MulReg(reg,razr);
5296
 
5297
					if(reg==AX){
5298
 
5299
						doregmath_32(ECX,razr,sign,&ofsstr);
5300
 
5301
					}
5302
 
5303
						do_e_axmath(0,razr,&ofsstr);
5304
 
5305
					}
5306
 
5307
					warningreg(regs[razr/2-1][sign]);
5308
 
5309
					op66(razr);
5310
 
5311
					op(0xC0+reg*8+sign);
5312
 
5313
				}
5314
 
5315
			break;
5316
 
5317
			getoperand(reg==BX?SI:BX);
5318
 
5319
			CheckMinusNum();
5320
 
5321
				ii=doconstlongmath();
5322
 
5323
				if(itok.type==tp_opperand){
5324
 
5325
					op(0x50+reg);	//push reg
5326
 
5327
					MovRegNum(razr,postnumflag&f_reloc,ii,EAX);
5328
 
5329
					ClearReg(AX);
5330
 
5331
				}
5332
 
5333
					if(vop!=0){
5334
 
5335
							op(0xB1); op(vop); /* MOV CL,num */
5336
 
5337
							op(0xE8+reg); // SHR reg,CL
5338
 
5339
							ClearReg(CX);
5340
 
5341
						else{
5342
 
5343
							op(0xC1);
5344
 
5345
		 					op(vop);
5346
 
5347
					}
5348
 
5349
				else{
5350
 
5351
						op66(razr);
5352
 
5353
					}
5354
 
5355
					if(reg!=EAX){
5356
 
5357
						op(0x90+reg);	//xchg reg,AX
5358
 
5359
						ClearReg(AX);
5360
 
5361
				}
5362
 
5363
			else if(itok2.type==tp_stopper){
5364
 
5365
					op66(razr);
5366
 
5367
				}
5368
 
5369
				next=0;
5370
 
5371
					op66(razr);
5372
 
5373
					warningreg(regs[razr/2-1][EAX]);
5374
 
5375
				}
5376
 
5377
			else{
5378
 
5379
				op(0x50+reg);	//push reg
5380
 
5381
				do_e_axmath(0,razr,&ofsstr);
5382
 
5383
				op66(razr);
5384
 
5385
				if(reg==EAX){
5386
 
5387
					warningreg(regs[razr/2-1][ECX]);
5388
 
5389
				}
5390
 
5391
				op(0x58+sign);	//pop sign
5392
 
5393
				op(0x90+sign);	//xchg AX,sign
5394
 
5395
				op(0xF7);
5396
 
5397
				op66(razr);
5398
 
5399
					if(optimizespeed){
5400
 
5401
						op(0xC0+reg);	//mov reg,AX
5402
 
5403
					else op(0x90+reg);	//xchg AX,sign
5404
 
5405
				warningreg(regs[razr/2-1][EAX]);
5406
 
5407
				next=0;
5408
 
5409
			break;
5410
 
5411
	}
5412
 
5413
	if(terminater==tk_semicolon)seminext();
5414
 
5415
//	puts("return doreg_32");
5416
 
5417
}
5418
 
5419
int optnumadd(unsigned long num,int reg,int razr,int vop)
5420
 
5421
int nrazr=0;
5422
 
5423
		if(vop==0x20){	//&=
5424
 
5425
			setzeroflag=TRUE;
5426
 
5427
		return TRUE;		//+= -= |= ^=
5428
 
5429
	if(vop==8){	//|=
5430
 
5431
		if((unsigned short)num<256&&razr==r16&®<4){
5432
 
5433
			else{
5434
 
5435
				op(0xc8+reg);
5436
 
5437
			op(num);
5438
 
5439
		}
5440
 
5441
			op66(r16);
5442
 
5443
			else{
5444
 
5445
				op(0xc8+reg);
5446
 
5447
			outword(num);
5448
 
5449
		}
5450
 
5451
	if(num==1){
5452
 
5453
			op66(razr);
5454
 
5455
			setzeroflag=TRUE;
5456
 
5457
		}
5458
 
5459
			op66(razr);
5460
 
5461
			setzeroflag=TRUE;
5462
 
5463
		}
5464
 
5465
	if(!optimizespeed&&num==2&&((razr==r16&&am32==FALSE)||(razr==r32&&am32))){
5466
 
5467
			op(0x48+reg);
5468
 
5469
			setzeroflag=TRUE;
5470
 
5471
		}
5472
 
5473
			op66(razr);
5474
 
5475
			op66(razr);
5476
 
5477
			setzeroflag=TRUE;
5478
 
5479
		}
5480
 
5481
	if((razr==r16&&(unsigned short)num==0xffff)||
5482
 
5483
		if(vop==0x28){	//-=
5484
 
5485
			op(0x40+reg);
5486
 
5487
			return TRUE;
5488
 
5489
		if(vop==0){	//+=
5490
 
5491
			op(0x48+reg);
5492
 
5493
			return TRUE;
5494
 
5495
		if(vop==0x20)return TRUE;	//&=
5496
 
5497
			if(optimizespeed&&(chip==5||chip==6))return FALSE;
5498
 
5499
			op(0xF7);
5500
 
5501
			setzeroflag=FALSE;
5502
 
5503
		}
5504
 
5505
	if(vop==0x20){	//&=
5506
 
5507
		if(razr==r16&&(unsigned short)num>=0xFF00&®<4){
5508
 
5509
			else{
5510
 
5511
				op(0xE0+reg);
5512
 
5513
			op(num);
5514
 
5515
		}
5516
 
5517
			op66(r16);
5518
 
5519
			else{
5520
 
5521
				op(0xE0+reg);
5522
 
5523
			outword(num);
5524
 
5525
		}
5526
 
5527
	if(!optimizespeed&&(razr==r16&&(unsigned short)num==0xfffe&&am32==FALSE)||
5528
 
5529
		if(vop==0x28){	//-=
5530
 
5531
			op(0x40+reg);
5532
 
5533
			return TRUE;
5534
 
5535
		if(vop==0){	//+=
5536
 
5537
			op(0x48+reg);
5538
 
5539
			return TRUE;
5540
 
5541
	}
5542
 
5543
		op66(razr);
5544
 
5545
		op(0xC0+vop+reg);
5546
 
5547
		setzeroflag=TRUE;
5548
 
5549
	}
5550
 
5551
}
5552
 
5553
int dobeg(int beg,int terminater)
5554
 
5555
unsigned char next=1;
5556
 
5557
int rettype=tk_beg,pointr=0;;
5558
 
5559
int numpointr=0;
5560
 
5561
	nexttok();
5562
 
5563
		case tk_assign:
5564
 
5565
				ofsstr=GetLecsem(terminater);
5566
 
5567
			else{
5568
 
5569
				if(RegToReg(beg,itok.number,r8)==NOINREG)goto nn1;
5570
 
5571
				break;
5572
 
5573
			if(ofsstr){
5574
 
5575
				if((retreg=CheckIDZReg(ofsstr,beg,r8))!=NOINREG){
5576
 
5577
					tok=tk_beg;
5578
 
5579
					goto nn1;
5580
 
5581
			}
5582
 
5583
			convert_type(&sign,&rrettype,&pointr,am32==TRUE?(beg>3?beg-4:beg):BX);
5584
 
5585
				nexttok();
5586
 
5587
			}
5588
 
5589
			if(tok2==tk_assign){
5590
 
5591
				if(ofsstr){
5592
 
5593
					ofsstr=NULL;
5594
 
5595
				if(beg!=hnumber){
5596
 
5597
					op(0xC0+beg+hnumber*8);	//mov beg,AL
5598
 
5599
				next=0;
5600
 
5601
					IDZToReg(ofsstr,beg,r8);
5602
 
5603
				}
5604
 
5605
			}
5606
 
5607
nn1:
5608
 
5609
				if(rrettype==tk_char||rrettype==tk_byte)rettype=doalmath(sign,&ofsstr);
5610
 
5611
				else rettype=do_e_axmath(sign,r32,&ofsstr);
5612
 
5613
			}
5614
 
5615
				if(rrettype==tk_char||rrettype==tk_byte||beg>BL){
5616
 
5617
					if(itok.type!=tp_stopper&&tok!=tk_eof){
5618
 
5619
						rettype=tk_beg;
5620
 
5621
				}
5622
 
5623
					if(rrettype==tk_int||rrettype==tk_word)next=r16;
5624
 
5625
					rettype=getintoreg(beg,next,sign,&ofsstr);
5626
 
5627
				next=0;
5628
 
5629
			if(ofsstr){
5630
 
5631
				free(ofsstr);
5632
 
5633
			break;
5634
 
5635
			ClearReg(beg>3?beg%4:beg);
5636
 
5637
		case tk_minusminus: op(0xFE); op(0xC8+beg);
5638
 
5639
			break;
5640
 
5641
			getoperand(beg==BL||beg==BH?SI:BX);
5642
 
5643
				case tk_charvar:
5644
 
5645
					CheckAllMassiv(bufrm,1,&strinf);
5646
 
5647
					op(0x86);
5648
 
5649
					outaddress(&itok);
5650
 
5651
					ClearReg(beg>3?beg-4:beg);
5652
 
5653
				case tk_beg:
5654
 
5655
						if(RegSwapReg(beg,itok.number,r8)==NOINREG){
5656
 
5657
							op(0xC0+(unsigned int)itok.number+beg*8);
5658
 
5659
						else waralreadinitreg(begs[beg],begs[itok.number]);
5660
 
5661
					break;
5662
 
5663
			}
5664
 
5665
		case tk_xorequals: vop+=0x08;
5666
 
5667
		case tk_andequals: vop+=0x18;
5668
 
5669
		case tk_plusequals:
5670
 
5671
			if(CheckAddOnly()){
5672
 
5673
				cha2=' ';
5674
 
5675
				else tok=tk_minus;
5676
 
5677
				else dobegmath(beg);
5678
 
5679
				break;
5680
 
5681
			getoperand(beg==BL||beg==BH?SI:BX);
5682
 
5683
				if(beg==AL){
5684
 
5685
					dobegmath(CL);
5686
 
5687
				}
5688
 
5689
					doalmath(0,&ofsstr);
5690
 
5691
				}
5692
 
5693
				op(0x00+vop);
5694
 
5695
				next=0;
5696
 
5697
			}
5698
 
5699
				case tk_number:
5700
 
5701
					next=0;
5702
 
5703
					if(i==255&&vop==0x20)break;
5704
 
5705
					else{
5706
 
5707
						op(0xC0+vop+beg);
5708
 
5709
					op(i);
5710
 
5711
				case tk_qwordvar:
5712
 
5713
				case tk_longvar:
5714
 
5715
					i+=2;
5716
 
5717
				case tk_intvar:
5718
 
5719
				case tk_charvar:
5720
 
5721
					i++;
5722
 
5723
					outseg(&itok,2);
5724
 
5725
					op(beg*8+itok.rm);
5726
 
5727
					break;
5728
 
5729
					op(0x00+vop);
5730
 
5731
					break;
5732
 
5733
				case tk_apiproc:
5734
 
5735
				case tk_declare:
5736
 
5737
				case tk_id:
5738
 
5739
					i=beg<4?beg:beg-4;
5740
 
5741
					addESP+=2;
5742
 
5743
					procdo(tk_byte);
5744
 
5745
						nexttok();
5746
 
5747
						next=0;
5748
 
5749
					addESP-=2;
5750
 
5751
					op(0x58+(i!=AX?i:CX));
5752
 
5753
						op(0x00+vop);
5754
 
5755
					}
5756
 
5757
						if(vop>0x20){
5758
 
5759
							op(0xC0+CL+beg);	//xchg al,cl
5760
 
5761
						op(0x00+vop);
5762
 
5763
					}
5764
 
5765
				case tk_reg:
5766
 
5767
						op(0x00+vop);
5768
 
5769
					}
5770
 
5771
					break;
5772
 
5773
				default: valueexpected();	break;
5774
 
5775
			break;
5776
 
5777
		case tk_llequals:
5778
 
5779
			ClearReg(beg>3?beg%4:beg);
5780
 
5781
				if((unsigned int)itok.number==1){
5782
 
5783
				}	/* SHL beg,1 */
5784
 
5785
					if(chip<2)goto shiftbeg;
5786
 
5787
						op(0xc0);
5788
 
5789
						op((unsigned int)itok.number);
5790
 
5791
				}
5792
 
5793
			else{
5794
 
5795
				if(beg!=CL){
5796
 
5797
						op(0xD2); op(0xE0+vop+beg); 	/* SHL beg,CL */
5798
 
5799
					else{
5800
 
5801
						getintobeg(CL,&ofsstr);
5802
 
5803
						next=0;
5804
 
5805
						op(0xD2); op(0xE0+vop+beg); 	/* SHL beg,CL */
5806
 
5807
				}
5808
 
5809
			}
5810
 
5811
		default: operatorexpected(); break;
5812
 
5813
	if(next)nexttok();
5814
 
5815
	return rettype;
5816
 
5817
5818
 
5819
{
5820
 
5821
int numpointr=0;
5822
 
5823
	if(seg==CS)preerror("CS not used for destention");
5824
 
5825
	if(seg==SS)RestoreStack();
5826
 
5827
	KillVar(segs[seg]);
5828
 
5829
		nexttok();
5830
 
5831
			nexttok();
5832
 
5833
		}
5834
 
5835
		if(tok2==tk_assign){
5836
 
5837
			if(ofsstr){
5838
 
5839
				ofsstr=NULL;
5840
 
5841
			goto getfromreg;
5842
 
5843
		if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr);
5844
 
5845
			switch(tok){
5846
 
5847
getfromreg:
5848
 
5849
					op(0xC0+seg*8+(unsigned int)itok.number);	/* MOV seg,reg */
5850
 
5851
				case tk_intvar:
5852
 
5853
				case tk_longvar:
5854
 
5855
				case tk_qwordvar:
5856
 
5857
					op66(r16);
5858
 
5859
					op(0x8E);
5860
 
5861
					outaddress(&itok);	 /* MOV seg,[wordvar] */
5862
 
5863
				case tk_seg:
5864
 
5865
						PushSeg((unsigned int)itok.number);
5866
 
5867
						break;
5868
 
5869
					goto segax;
5870
 
5871
					if(regoverstack&&chip>1){
5872
 
5873
						if(short_ok(itok.number)&&(itok.flag&f_reloc)==0){
5874
 
5875
							op(itok.number);
5876
 
5877
						else{
5878
 
5879
							if((itok.flag&f_reloc)!=0)AddReloc();
5880
 
5881
							else outword(itok.number);
5882
 
5883
						PopSeg(seg);
5884
 
5885
						break;
5886
 
5887
					goto segax;
5888
 
5889
			}
5890
 
5891
		else{
5892
 
5893
			do_e_axmath(0,r16,&ofsstr);
5894
 
5895
			op(0xC0+seg*8);
5896
 
5897
		}
5898
 
5899
	else if(tok==tk_swap){
5900
 
5901
		switch(tok){
5902
 
5903
			case tk_wordvar:
5904
 
5905
				op66(r16);
5906
 
5907
				op(0xC0+seg*8); /* MOV AX,SEG */
5908
 
5909
				op66(r16);
5910
 
5911
				op(0x87);
5912
 
5913
				outaddress(&itok);	/* XCHG AX,[word] */
5914
 
5915
				op(0x8E);
5916
 
5917
				break;
5918
 
5919
				KillVar(segs[itok.number]);
5920
 
5921
				PushSeg(itok.number);
5922
 
5923
				PopSeg(itok.number);
5924
 
5925
			default: preerror("Only int, word variables valid for segment register ><");
5926
 
5927
		}
5928
 
5929
	else segoperror();
5930
 
5931
	else seminext();
5932
 
5933
5934
 
5935
{
5936
 
5937
		case DS: op(0x1E); break;
5938
 
5939
		case SS: op(0x16); break;
5940
 
5941
		case FS: outword(0xA00F); if(cpu<3)cpu=3; break;
5942
 
5943
	}
5944
 
5945
5946
 
5947
{
5948
 
5949
		case DS: op(0x1F); break;
5950
 
5951
		case ES: op(0x07); break;
5952
 
5953
		case GS: outword(0xA90F); if(cpu<3)cpu=3;  break;
5954
 
5955
}
5956
 
5957
// =============== doregmath_32(), dobegmath() ===============
5958
 
5959
void doregmath_32(int reg,int razr,int sign,char **ofsstr,int fdiv)  // math done is on all regs except AX
5960
 
5961
{
5962
 
5963
	while(itok.type!=tp_stopper&&tok!=tk_eof){
5964
 
5965
			NegReg(razr,reg);
5966
 
5967
		}
5968
 
5969
		optnum=FALSE;
5970
 
5971
		CheckConstVar3(&tok2,&itok2,razr);
5972
 
5973
#endif
5974
 
5975
			if(razr==r32){
5976
 
5977
			}
5978
 
5979
			if(itok.type==tp_stopper||tok==tk_eof)break;
5980
 
5981
		if(tok2==tk_number)optnum=OptimNum();
5982
 
5983
			case tk_xor: vop+=0x08;
5984
 
5985
			case tk_and: vop+=0x18;
5986
 
5987
			case tk_plus:
5988
 
5989
				else tok=tk_number;
5990
 
5991
					case tk_number:
5992
 
5993
					case tk_postnumber:
5994
 
5995
						op66(razr);
5996
 
5997
						op(0xC0+vop+reg);
5998
 
5999
						else if(tok==tk_undefofs)AddUndefOff(0,itok.name);
6000
 
6001
						razr==r16?outword((unsigned int)itok.number):outdword(itok.number);
6002
 
6003
					case tk_apioffset:
6004
 
6005
					  op(0x81);
6006
 
6007
						AddApiToPost(itok.number);
6008
 
6009
					case tk_doublevar:
6010
 
6011
					case tk_floatvar:
6012
 
6013
						itok.number=EAX;
6014
 
6015
						goto defreg32;
6016
 
6017
						int vops,reg2s;
6018
 
6019
						if(i<=64)vops=r64;
6020
 
6021
						if(i<=16)vops=r16;
6022
 
6023
						reg2s=CX;
6024
 
6025
						bits2reg(reg2s,vops);
6026
 
6027
						warningreg(regs[vops/2-1][reg2s]);
6028
 
6029
						goto defreg32;
6030
 
6031
						if(razr==r32){
6032
 
6033
							outword(0xB70F);
6034
 
6035
								op(0xC0+reg);
6036
 
6037
							}
6038
 
6039
							warningreg(regs[razr/2-1][itok.number]);
6040
 
6041
					case tk_reg32:
6042
 
6043
						op66(razr);
6044
 
6045
						op(0xC0+reg+(unsigned int)itok.number*8);
6046
 
6047
					case tk_qwordvar:
6048
 
6049
					case tk_dwordvar:
6050
 
6051
						goto wordvar;
6052
 
6053
					case tk_wordvar:
6054
 
6055
						i=2;
6056
 
6057
						CheckAllMassiv(bufrm,i,&strinf);
6058
 
6059
						outseg(&itok,2);
6060
 
6061
						op(reg*8+itok.rm);
6062
 
6063
						break;
6064
 
6065
					case tk_beg:
6066
 
6067
					case tk_seg:
6068
 
6069
addchar:
6070
 
6071
						ITOK wtok;
6072
 
6073
						wstr=strinf;
6074
 
6075
						wbuf=bufrm;
6076
 
6077
						wtok=itok;
6078
 
6079
						goto addax;
6080
 
6081
					case tk_id:
6082
 
6083
					case tk_apiproc:
6084
 
6085
					case tk_declare:
6086
 
6087
						if(!(comfile==file_w32&&(reg==EBX||reg==EDI||reg==ESI))){
6088
 
6089
							op(0x50+reg);	//push AX
6090
 
6091
						addESP+=razr==r16?2:4;
6092
 
6093
						addstack=FALSE;
6094
 
6095
						addstack=oaddstack;
6096
 
6097
						if(!(comfile==file_w32&&(reg==EBX||reg==EDI||reg==ESI))){
6098
 
6099
							op(0x58+reg);
6100
 
6101
addax:
6102
 
6103
						op(0x01+vop);
6104
 
6105
						warningreg(regs[razr/2-1][0]);
6106
 
6107
					default: valueexpected(); break;
6108
 
6109
				break;
6110
 
6111
			case tk_andminus: vop+=0x18;
6112
 
6113
			  getoperand(reg==BX?SI:BX);
6114
 
6115
					case tk_number:
6116
 
6117
						op66(razr);
6118
 
6119
						op(0xC0+vop+reg);
6120
 
6121
						razr==r16?outword((unsigned int)itok.number):outdword(itok.number);
6122
 
6123
					case tk_ID:
6124
 
6125
					case tk_proc:
6126
 
6127
					case tk_undefproc:
6128
 
6129
 
6130
 
6131
						if(*ofsstr!=NULL){
6132
 
6133
							*ofsstr=NULL;
6134
 
6135
						goto defxormin;
6136
 
6137
						if(reg==ECX){
6138
 
6139
							SINFO wstr;
6140
 
6141
							strinf.bufstr=NULL;
6142
 
6143
							char *wbuf;
6144
 
6145
							bufrm=NULL;
6146
 
6147
							getinto_e_ax(sign,tok,&wtok,wbuf,&wstr,razr);
6148
 
6149
						else{
6150
 
6151
							getintoreg_32(CX,razr,sign,ofsstr,FALSE);
6152
 
6153
defxormin:
6154
 
6155
					 	op66(razr);
6156
 
6157
						op(0xC0+i*8+reg);
6158
 
6159
						if(i==ECX)continue;
6160
 
6161
				}
6162
 
6163
			case tk_rrminus:
6164
 
6165
					regmathoperror();
6166
 
6167
				}
6168
 
6169
				getintobeg(CL,ofsstr);
6170
 
6171
				op(0xD3);
6172
 
6173
				warningreg(begs[1]);
6174
 
6175
			case tk_rr:
6176
 
6177
				if(RshiftReg(razr,reg,sign)==FALSE)regmathoperror();
6178
 
6179
				break;
6180
 
6181
				if(reg==ECX){
6182
 
6183
					break;
6184
 
6185
				tok=tk_minus;
6186
 
6187
			case tk_ll:
6188
 
6189
				if(tok==tk_number){
6190
 
6191
						regmathoperror();
6192
 
6193
					}
6194
 
6195
				}
6196
 
6197
					op66(razr);
6198
 
6199
 
6200
 
6201
				else if(reg!=ECX){
6202
 
6203
					getintobeg(CL,ofsstr);
6204
 
6205
					op(0xD3);
6206
 
6207
					warningreg(begs[1]);
6208
 
6209
				}
6210
 
6211
				break;
6212
 
6213
			case tk_mult:
6214
 
6215
				else tok=tk_number;
6216
 
6217
					itok.number=-itok.number;
6218
 
6219
				}
6220
 
6221
				break;
6222
 
6223
			case tk_mod:
6224
 
6225
				goto divcalc;
6226
 
6227
			case tk_div:
6228
 
6229
			  if(optnum==FALSE)getoperand(reg==BX?SI:BX);
6230
 
6231
				if(negflag&&tok==tk_number){
6232
 
6233
					negflag=FALSE;
6234
 
6235
				if(tok==tk_number&&(i=caselong(itok.number))!=NUMNUM){
6236
 
6237
						itok.number--;
6238
 
6239
							ZeroReg(reg,razr);
6240
 
6241
						else if(short_ok(itok.number,razr/2-1)){
6242
 
6243
							op(0x83);
6244
 
6245
							op(itok.number);
6246
 
6247
						else{
6248
 
6249
							op(0x81);
6250
 
6251
							razr==r16?outword((unsigned int)itok.number):outdword(itok.number);
6252
 
6253
					}
6254
 
6255
						if(i!=0){
6256
 
6257
								if(reg==CX)regmathoperror();
6258
 
6259
								op(0xD3);
6260
 
6261
								warningreg(begs[1]);
6262
 
6263
							else{
6264
 
6265
								op(0xC1);
6266
 
6267
		 						op(i);
6268
 
6269
						}
6270
 
6271
					break;
6272
 
6273
				if(fdiv!=1){
6274
 
6275
					op(0x90+reg);	//xchg AX,reg
6276
 
6277
				DivMod(vop,sign,razr,0);
6278
 
6279
					if(vop==1){
6280
 
6281
						if(optimizespeed)outword(0xC28B);	//mov ax,dx
6282
 
6283
					}
6284
 
6285
				}
6286
 
6287
					if(reg!=EDX){
6288
 
6289
						op(0x89);
6290
 
6291
					}
6292
 
6293
					continue;
6294
 
6295
				op66(razr);
6296
 
6297
					op(0x89);
6298
 
6299
				}
6300
 
6301
				warningreg(regs[razr/2-1][EAX]);
6302
 
6303
			default: operatorexpected(); break;
6304
 
6305
		calcnumber=FALSE;
6306
 
6307
		nexttok();
6308
 
6309
	calcnumber=FALSE;
6310
 
6311
	if(razr==r32&&cpu<3)cpu=3;
6312
 
6313
6314
 
6315
// all other registers preserved
6316
 
6317
int vop,i,optnum=FALSE,negflag=FALSE;
6318
 
6319
		vop=0;
6320
 
6321
#ifdef OPTVARCONST
6322
 
6323
			if(CheckConstVar(&itok2)){
6324
 
6325
				calcnumber=TRUE;
6326
 
6327
		}
6328
 
6329
		if(tok2==tk_number)optnum=OptimNum();
6330
 
6331
		switch(tok){
6332
 
6333
			case tk_minus: vop+=0x08;
6334
 
6335
			case tk_or: vop+=0x08;
6336
 
6337
			  if(optnum==FALSE)getoperand(beg==BL||beg==BH?SI:BX);
6338
 
6339
					tok=tk_number;
6340
 
6341
				}
6342
 
6343
					case tk_number:
6344
 
6345
						else if(itok.number==1){
6346
 
6347
								op(0xFE);
6348
 
6349
								break;
6350
 
6351
							if(oldtok==tk_minus){
6352
 
6353
								op(0xC8+beg);
6354
 
6355
							}
6356
 
6357
						else if((unsigned char)itok.number==0xff){
6358
 
6359
								op(0xFE);
6360
 
6361
								break;
6362
 
6363
							if(oldtok==tk_plus){
6364
 
6365
								op(0xC8+beg);
6366
 
6367
							}
6368
 
6369
					  op(0x80);
6370
 
6371
						op((unsigned int)itok.number);
6372
 
6373
					case tk_bits:
6374
 
6375
						i=itok.bit.siz+itok.bit.ofs;
6376
 
6377
						if(i<=32)vops=r32;
6378
 
6379
						if(i<=8)vops=r8;
6380
 
6381
						if(beg==CL)reg2s=BL;
6382
 
6383
						if(vops==r64)vops=r32;
6384
 
6385
						itok.number=reg2s;
6386
 
6387
						op(0x00+vop);
6388
 
6389
						break;
6390
 
6391
						i=4;
6392
 
6393
					case tk_dwordvar:
6394
 
6395
					case tk_intvar:
6396
 
6397
						i++;
6398
 
6399
					case tk_charvar:
6400
 
6401
						CheckAllMassiv(bufrm,i,&strinf);
6402
 
6403
						op(0x02+vop);
6404
 
6405
						outaddress(&itok);
6406
 
6407
					case tk_postnumber:
6408
 
6409
					case tk_rmnumber: begworderror();	break;
6410
 
6411
					case tk_id:
6412
 
6413
					case tk_apiproc:
6414
 
6415
					case tk_declare:
6416
 
6417
						if(beg!=AL){
6418
 
6419
							op(0xc0+beg);
6420
 
6421
						break;
6422
 
6423
				}
6424
 
6425
			case tk_xorminus: vop+=0x10;
6426
 
6427
			case tk_orminus: vop+=0x08;
6428
 
6429
				if(tok==tk_number){
6430
 
6431
					op(0x80);
6432
 
6433
					op((unsigned int)itok.number);
6434
 
6435
				else negregerror();
6436
 
6437
			case tk_rr:
6438
 
6439
			case tk_ll:
6440
 
6441
				if(tok==tk_number){
6442
 
6443
						if(vop==0){
6444
 
6445
							op(0xC0+9*beg); // ADD reg,reg
6446
 
6447
						else{
6448
 
6449
						}
6450
 
6451
					else if((unsigned int)itok.number!=0){
6452
 
6453
						else{
6454
 
6455
							op(0xe0+beg+vop); // SHL reg,imm8
6456
 
6457
							if(cpu<2)cpu=2;
6458
 
6459
					}
6460
 
6461
				else if(tok==tk_beg&&itok.number==CL&&beg!=CL){
6462
 
6463
					op(0xE0+beg+vop);	// SHL xXX,CL
6464
 
6465
				else begmathoperror();
6466
 
6467
			case tk_multminus: negflag=TRUE;
6468
 
6469
			  if(optnum==FALSE)getoperand(beg==BL||beg==BH?SI:BX);
6470
 
6471
					tok=tk_number;
6472
 
6473
				}
6474
 
6475
					itok.number=-itok.number;
6476
 
6477
				}
6478
 
6479
					case tk_number:
6480
 
6481
						switch((unsigned int)itok.number){
6482
 
6483
								outword(0x00B0+beg);
6484
 
6485
							case 2:
6486
 
6487
								op(0xC0+9*beg); // beg * 2 = ADD beg,beg
6488
 
6489
							default:
6490
 
6491
								if(vop!=NUMNUM){
6492
 
6493
									else{
6494
 
6495
										op(0xe0+beg);	//SHL beg,num
6496
 
6497
										if(cpu<1)cpu=1;
6498
 
6499
								}
6500
 
6501
						}
6502
 
6503
					default: begmathoperror(); break;
6504
 
6505
				break;
6506
 
6507
			case tk_modminus:
6508
 
6509
			case tk_mod:
6510
 
6511
			case tk_llminus:
6512
 
6513
			default: operatorexpected(); break;
6514
 
6515
#ifdef OPTVARCONST
6516
 
6517
#endif
6518
 
6519
		ClearReg(beg%4);
6520
 
6521
}
6522
 
6523
// ============= getintoreg_32(), getintobeg() ============
6524
 
6525
int getintoreg_32(int reg,int razr,int sign,char **ofsstr,int useloop)	// get into word reg (except AX) with enum
6526
 
6527
int negflag=0,next=1,i=0;
6528
 
6529
unsigned long holdnumber=0;
6530
 
6531
int rettype=tk_reg;
6532
 
6533
//				printf("line %d tok=%d %s\n",linenumber,tok,itok.name);
6534
 
6535
		if(reg==idxregs[1]||reg==idxregs[2]){
6536
 
6537
			if(reg==idxregs[1])reg2=idxregs[0];
6538
 
6539
	}
6540
 
6541
		reg1=reg;
6542
 
6543
	}
6544
 
6545
		if(CheckMinusNum()==FALSE){
6546
 
6547
			getoperand(am32==FALSE?BX:reg);
6548
 
6549
	}
6550
 
6551
6552
 
6553
		if(razr==r32){
6554
 
6555
			if(Reg32ToLea(reg)){
6556
 
6557
			}
6558
 
6559
		else
6560
 
6561
				return tk_reg;
6562
 
6563
	}
6564
 
6565
6566
 
6567
	CheckConstVar3(&tok,&itok,razr);
6568
 
6569
#endif
6570
 
6571
//	printf("reg=%d tok=%d\n",reg,tok);
6572
 
6573
		case tk_number:
6574
 
6575
			else{
6576
 
6577
				if(loop==0)oflag=postnumflag;
6578
 
6579
				loop++;
6580
 
6581
					nexttok();
6582
 
6583
					goto loopswitch1;
6584
 
6585
				if(tok==tk_plus&&tok2==tk_postnumber){
6586
 
6587
//		 		getoperand(am32==TRUE?EAX:BX);
6588
 
6589
				}
6590
 
6591
				next=0;
6592
 
6593
			break;
6594
 
6595
		case tk_undefofs:
6596
 
6597
				op66(razr);
6598
 
6599
				swap=1;
6600
 
6601
			if(tok==tk_undefofs){
6602
 
6603
//				AddUndefOff(0,itok.name);
6604
 
6605
			}
6606
 
6607
			if(useloop==FALSE)holdnumber=itok.number;
6608
 
6609
				tok=tk_number;
6610
 
6611
				if(otok!=tk_postnumber){
6612
 
6613
					else oflag^=postnumflag;
6614
 
6615
				}
6616
 
6617
					nexttok();
6618
 
6619
				}
6620
 
6621
				next=0;
6622
 
6623
			if(useloop&&(oflag&f_reloc))AddReloc();
6624
 
6625
			else outdword(holdnumber);
6626
 
6627
			break;
6628
 
6629
			op66(razr);
6630
 
6631
			AddApiToPost(itok.number);
6632
 
6633
			break;
6634
 
6635
			CheckAllMassiv(bufrm,itok.size,&strinf,&itok,reg1,reg2);
6636
 
6637
					(reg==SI||reg==DI||reg==BX)))break;
6638
 
6639
			op67(itok.sib==CODE16?r16:r32);
6640
 
6641
			op(0x8D);			// LEA reg,[rm]
6642
 
6643
			if(itok.post!=0&&itok.post!=UNDEF_OFSET){
6644
 
6645
					unsigned int ooutptr=outptr;
6646
 
6647
					setwordpost(&itok);
6648
 
6649
				}
6650
 
6651
			}
6652
 
6653
			else{
6654
 
6655
				oitok=itok;
6656
 
6657
				itok.rm=tk_dword;
6658
 
6659
				outaddress(&oitok);
6660
 
6661
			}
6662
 
6663
			break;
6664
 
6665
			i=4;
6666
 
6667
		case tk_dwordvar:
6668
 
6669
dwordvar:
6670
 
6671
	 		op66(razr);
6672
 
6673
			op(0x8B);
6674
 
6675
			outaddress(&itok);
6676
 
6677
			break;
6678
 
6679
		case tk_wordvar:
6680
 
6681
			if(razr==r16)goto dwordvar;
6682
 
6683
			if(tok==tk_wordvar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){
6684
 
6685
	 			op66(r16);
6686
 
6687
				op(0x8B);
6688
 
6689
			else{
6690
 
6691
				outseg(&itok,3);	//movxx reg,var
6692
 
6693
			}
6694
 
6695
			outaddress(&itok);
6696
 
6697
			break;
6698
 
6699
			i=4;
6700
 
6701
			Float2reg32(reg,i,reg1,reg2);
6702
 
6703
			break;
6704
 
6705
		case tk_charvar:
6706
 
6707
				CheckAllMassiv(bufrm,1,&strinf,&itok,reg1,reg2);
6708
 
6709
					ZeroReg(reg,razr);
6710
 
6711
					op(0x8A);
6712
 
6713
				else{
6714
 
6715
					outseg(&itok,3);
6716
 
6717
					if(tok==tk_bytevar)op(0xb6);
6718
 
6719
				}
6720
 
6721
				outaddress(&itok);
6722
 
6723
				break;
6724
 
6725
			if(reg<=BX){
6726
 
6727
					outseg(&itok,1);
6728
 
6729
					outword((unsigned int)itok.number);
6730
 
6731
				else{
6732
 
6733
					outseg(&itok,2);
6734
 
6735
					op(reg*8+itok.rm); // MOV regL,[byte]
6736
 
6737
				}
6738
 
6739
				op(0x30); op(0xC0+(reg+4)*9); // XOR regH,regH
6740
 
6741
			else regbyteerror();
6742
 
6743
		case tk_reg:
6744
 
6745
				if(tok2==tk_openbracket){	//вызов процедуры по адресу в регистре
6746
 
6747
					nexttok();
6748
 
6749
					if(comfile==file_w32)swapparam();
6750
 
6751
					op66(r16);
6752
 
6753
					op(0xD0+reg1); 	/* CALL reg with stack params */
6754
 
6755
					clearregstat();
6756
 
6757
					FreeGlobalConst();
6758
 
6759
				}
6760
 
6761
					ZeroReg(reg,r32);
6762
 
6763
					op(0xC0+reg+(unsigned int)itok.number*8);
6764
 
6765
				else{
6766
 
6767
					outword(0xB70F);
6768
 
6769
				}
6770
 
6771
				break;
6772
 
6773
 
6774
 
6775
				reg1=itok.number;
6776
 
6777
				nexttok();
6778
 
6779
				if(comfile==file_w32)swapparam();
6780
 
6781
				op66(reg2);
6782
 
6783
				op(0xD0+reg1); 	/* CALL reg with stack params */
6784
 
6785
				clearregstat();
6786
 
6787
				FreeGlobalConst();
6788
 
6789
			}
6790
 
6791
				op66(razr);
6792
 
6793
				op(0xC0+reg+(unsigned int)itok.number*8);
6794
 
6795
			}
6796
 
6797
 
6798
 
6799
			i=itok.bit.siz+itok.bit.ofs;
6800
 
6801
			if(i<=32)vops=r32;
6802
 
6803
			bits2reg(reg,(razr
6804
 
6805
		case tk_seg:
6806
 
6807
			op(0x8C);
6808
 
6809
			ClearReg(reg);
6810
 
6811
		case tk_beg:
6812
 
6813
				if(optimizespeed&&chip>3&&chip<7&®<4&®!=(int)(itok.number%4)){
6814
 
6815
					op(0x88);
6816
 
6817
				}
6818
 
6819
					op66(razr);
6820
 
6821
 
6822
 
6823
			}
6824
 
6825
			else{
6826
 
6827
				op(0x30); op(0xC0+(reg+4)*9);	// XOR regH,regH
6828
 
6829
			ClearReg(reg);
6830
 
6831
		case tk_at:
6832
 
6833
			i++;
6834
 
6835
		case tk_id:
6836
 
6837
		case tk_apiproc:
6838
 
6839
		case tk_declare:
6840
 
6841
			if((!i)||macros(razr==r16?tk_word:tk_dword)==0)procdo(razr==r16?tk_word:tk_dword);
6842
 
6843
			tok=(razr==r16?tk_reg:tk_reg32);
6844
 
6845
				free(*ofsstr);
6846
 
6847
			}
6848
 
6849
			goto loopswitch;
6850
 
6851
		case tk_string:
6852
 
6853
			op(0xB8+reg);
6854
 
6855
				if(am32)dwordvalexpected();
6856
 
6857
			}
6858
 
6859
			ClearReg(reg);
6860
 
6861
		default: valueexpected();	break;
6862
 
6863
#ifdef OPTVARCONST
6864
 
6865
#endif
6866
 
6867
	if(swap){
6868
 
6869
		RegMulNum(reg,holdnumber,razr,0,&negflag,oflag);
6870
 
6871
	}
6872
 
6873
//		printf("tok=%d num=%d tok2=%d\n",tok,itok.number,tok2);
6874
 
6875
}
6876
 
6877
int getintobeg(int beg,char **ofsstr)	// get into beg (CL,DL,BL not others) with enum
6878
 
6879
int negflag=0,i=0;
6880
 
6881
	if(tok==tk_minus){
6882
 
6883
			negflag=1;
6884
 
6885
		}
6886
 
6887
#ifdef OPTVARCONST
6888
 
6889
//		printf("type1=%d type2=%d\n",itok.type,itok2.type);
6890
 
6891
			tok=tk_number;
6892
 
6893
		}
6894
 
6895
#endif
6896
 
6897
		case tk_number:
6898
 
6899
			i=(int)doconstlongmath();
6900
 
6901
			ConstToReg(i,beg,r8);
6902
 
6903
		case tk_rmnumber:
6904
 
6905
			op66(r16);
6906
 
6907
			if(itok.post==0)outseg(&itok,2);
6908
 
6909
			op(beg*8+itok.rm);
6910
 
6911
				if((itok.flag&f_extern)==0){
6912
 
6913
					if(am32&&itok.rm==rm_sib)outptr++;
6914
 
6915
					outptr=ooutptr;
6916
 
6917
				else setwordext(&itok.number);
6918
 
6919
			outaddress(&itok);
6920
 
6921
			break;
6922
 
6923
			op66(r16);
6924
 
6925
			(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
6926
 
6927
			nexttok();
6928
 
6929
			break;
6930
 
6931
			i=4;
6932
 
6933
		case tk_dwordvar:
6934
 
6935
		case tk_intvar:
6936
 
6937
			i++;
6938
 
6939
		case tk_bytevar:
6940
 
6941
			CheckAllMassiv(bufrm,i,&strinf);
6942
 
6943
			op(0x8A);
6944
 
6945
			outaddress(&itok);
6946
 
6947
			ClearReg(beg%4);
6948
 
6949
		case tk_doublevar:
6950
 
6951
		case tk_floatvar:
6952
 
6953
			if(beg>3){
6954
 
6955
				op(0xC0+beg+8*(beg-4));
6956
 
6957
			nexttok();
6958
 
6959
			break;
6960
 
6961
			int vops;
6962
 
6963
			if(i<=64)vops=r64;
6964
 
6965
			if(i<=16)vops=r16;
6966
 
6967
			if(beg>BX&&vops!=r8){
6968
 
6969
				op(0x50);
6970
 
6971
				addESP+=vops==r16?2:4;
6972
 
6973
				op(0x88);
6974
 
6975
				op66(vops==r64?r32:vops);
6976
 
6977
				op(0x58);
6978
 
6979
			else bits2reg(beg,vops);
6980
 
6981
			break;
6982
 
6983
			if(beg!=(int)itok.number){
6984
 
6985
				op(0xC0+beg+(unsigned int)itok.number*8);
6986
 
6987
			}
6988
 
6989
			break;
6990
 
6991
		case tk_reg:
6992
 
6993
				if(beg!=(int)itok.number){
6994
 
6995
					op(0x89);
6996
 
6997
					RegToReg(beg,itok.number,r8);
6998
 
6999
			}
7000
 
7001
			nexttok();
7002
 
7003
		case tk_seg:
7004
 
7005
			op(0x8C);
7006
 
7007
			nexttok();
7008
 
7009
			break;
7010
 
7011
		case tk_id:
7012
 
7013
		case tk_apiproc:
7014
 
7015
		case tk_declare:
7016
 
7017
			procdo(tk_byte);
7018
 
7019
			op(0xc0+beg);
7020
 
7021
			RegToReg(beg,AL,r8);
7022
 
7023
				free(*ofsstr);
7024
 
7025
			}
7026
 
7027
		default: valueexpected();	nexttok(); return 0;
7028
 
7029
#ifdef OPTVARCONST
7030
 
7031
#endif
7032
 
7033
		if(optimizespeed&&(chip==5||chip==6)){
7034
 
7035
			op(0xF0+beg);
7036
 
7037
			op(0xFE);
7038
 
7039
		}
7040
 
7041
			op(0xF6);
7042
 
7043
		}
7044
 
7045
	}
7046
 
7047
}
7048
 
7049
void  outaddress(ITOK *outtok)
7050
 
7051
int rm=outtok->rm;
7052
 
7053
		if(rm==rm_d16){
7054
 
7055
				AddUndefOff(2,outtok->name);
7056
 
7057
			}
7058
 
7059
		}
7060
 
7061
			rm&=rm_mod11;
7062
 
7063
			else if(rm==rm_mod10){
7064
 
7065
					AddUndefOff(2,outtok->name);
7066
 
7067
				}
7068
 
7069
			}
7070
 
7071
		}
7072
 
7073
	else{
7074
 
7075
			if(outtok->post==UNDEF_OFSET){
7076
 
7077
				outtok->post=0;
7078
 
7079
			outdword(outtok->number);
7080
 
7081
		else{
7082
 
7083
				op(outtok->sib);
7084
 
7085
					if(outtok->post==UNDEF_OFSET){
7086
 
7087
						outtok->post=0;
7088
 
7089
					outdword(outtok->number);
7090
 
7091
			}
7092
 
7093
			if(rm==rm_mod11)internalerror(badadr);
7094
 
7095
				if(outtok->post==UNDEF_OFSET){
7096
 
7097
					outtok->post=0;
7098
 
7099
				outdword(outtok->number);
7100
 
7101
			else if(rm==rm_mod01)op(outtok->number);
7102
 
7103
	}
7104
 
7105
7106
 
7107
 Обработка float
7108
 
7109
 --------------------------------------------------*/
7110
 
7111
{
7112
 
7113
unsigned int vop=0,rettype=tk_float,posiblret=tk_float,sign=0;
7114
 
7115
ITOK wtok;
7116
 
7117
int pointr=0;
7118
 
7119
int type=tk_floatvar;
7120
 
7121
		rettype=posiblret=tk_double;
7122
 
7123
		type=tk_doublevar;
7124
 
7125
	wstr=strinf;
7126
 
7127
	wtok=itok;
7128
 
7129
	bufrm=NULL;
7130
 
7131
char *ofsstr=NULL;
7132
 
7133
	switch(tok){
7134
 
7135
			getoperand(am32==TRUE?EAX:BX);
7136
 
7137
			if(tok2==tk_assign){
7138
 
7139
				next=0;
7140
 
7141
			}
7142
 
7143
			if(itok2.type==tp_opperand){	//составное
7144
 
7145
					if(OnlyNumber(rettype==tk_float?2:3)){
7146
 
7147
						itok.flag=(unsigned char)postnumflag;
7148
 
7149
						goto numbertovar;
7150
 
7151
				}
7152
 
7153
				if(rettype==tk_char||rettype==tk_byte)doalmath(sign,&ofsstr);
7154
 
7155
				else if(rettype==tk_long||rettype==tk_dword)do_e_axmath(sign,r32,&ofsstr);
7156
 
7157
			}
7158
 
7159
				switch(tok){
7160
 
7161
numbertovar:
7162
 
7163
							if(itok.rm==tk_double)itok.fnumber=itok.dnumber;
7164
 
7165
								float temp=itok.number;
7166
 
7167
							}
7168
 
7169
						else{
7170
 
7171
							else if(itok.rm!=tk_double)itok.dnumber=itok.lnumber;
7172
 
7173
						CheckAllMassiv(wbuf,razr,&wstr,&wtok);
7174
 
7175
							op66(r32);
7176
 
7177
								outseg(&wtok,2);
7178
 
7179
								op(wtok.rm+0x20);
7180
 
7181
								op(0);
7182
 
7183
							else if(regoverstack&&short_ok(itok.number,TRUE)&&(itok.flag&f_reloc)==0){
7184
 
7185
 
7186
 
7187
								outseg(&wtok,2);
7188
 
7189
								op(wtok.rm);
7190
 
7191
							}
7192
 
7193
								outseg(&wtok,2);
7194
 
7195
								op(wtok.rm);
7196
 
7197
								if((itok.flag&f_reloc)!=0)AddReloc();
7198
 
7199
							}
7200
 
7201
							itok.lnumber>>=32;
7202
 
7203
							compressoffset(&wtok);
7204
 
7205
						break;
7206
 
7207
					case tk_floatvar:
7208
 
7209
						ITOK w1tok;
7210
 
7211
						w1buf=bufrm;
7212
 
7213
						w1tok=itok;
7214
 
7215
						w1str=strinf;
7216
 
7217
						getinto_e_ax(0,tok==tk_floatvar?tk_dwordvar:tk_qwordvar,&w1tok,w1buf,&w1str,r32);
7218
 
7219
							if((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&wtok.sib==CODE32)){
7220
 
7221
								outseg(&wtok,1);
7222
 
7223
								if(am32)outdword(wtok.number);
7224
 
7225
							}
7226
 
7227
 
7228
 
7229
								outseg(&wtok,2);
7230
 
7231
								outaddress(&wtok);
7232
 
7233
							itok.number+=4;
7234
 
7235
							wtok.number+=4;
7236
 
7237
							ITOK w1tok;
7238
 
7239
							w1buf=bufrm;
7240
 
7241
							w1tok=itok;
7242
 
7243
							w1str=strinf;
7244
 
7245
							getinto_e_ax(0,tk_qwordvar,&w1tok,w1buf,&w1str,r32);
7246
 
7247
						getfromEAX=1;
7248
 
7249
					default:
7250
 
7251
						if((i=doeaxfloatmath(tk_fpust))==tk_fpust||i==tk_double){
7252
 
7253
							if(retrez==tk_floatvar||retrez==tk_doublevar){
7254
 
7255
								outseg(&wtok,2);
7256
 
7257
								op(wtok.rm+0x18);
7258
 
7259
								fwait3();
7260
 
7261
							else retrez=tk_fpust;
7262
 
7263
						else getfromEAX=1;
7264
 
7265
				}
7266
 
7267
			if(getfromEAX){
7268
 
7269
				retrez=tk_reg32;
7270
 
7271
				if((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&wtok.sib==CODE32)){
7272
 
7273
					outseg(&wtok,1);
7274
 
7275
					if(am32)outdword(wtok.number);
7276
 
7277
				}
7278
 
7279
					CheckAllMassiv(wbuf,4,&wstr,&wtok);
7280
 
7281
					outseg(&wtok,2);
7282
 
7283
					outaddress(&wtok);
7284
 
7285
			}
7286
 
7287
		case tk_minusminus:
7288
 
7289
		case tk_plusplus:
7290
 
7291
			outword(0xe8d9);	//fld1
7292
 
7293
			outseg(&wtok,2);	//fadd var
7294
 
7295
			op(wtok.rm+vop);
7296
 
7297
			if(retrez==tk_floatvar||retrez==tk_doublevar){
7298
 
7299
				op(0xd9+addop);
7300
 
7301
				outaddress(&wtok);
7302
 
7303
			}
7304
 
7305
		case tk_divequals: vop+=0x10;
7306
 
7307
		case tk_multequals: vop+=8;
7308
 
7309
			getoperand(am32==TRUE?EAX:BX);
7310
 
7311
				if(tok==tk_number){
7312
 
7313
							(itok.rm==tk_double&&itok.dnumber==1.0)||
7314
 
7315
						if(vop==0||vop==0x28)goto incvar;
7316
 
7317
					}
7318
 
7319
							(itok.rm==tk_double&&itok.dnumber==0.0)||itok.lnumber==0){
7320
 
7321
							case 0x38:
7322
 
7323
								break;
7324
 
7325
								outword(0xEED9);	//FLDZ
7326
 
7327
									CheckAllMassiv(wbuf,razr,&wstr,&wtok);
7328
 
7329
									op(0xd9+addop);
7330
 
7331
									outaddress(&wtok);
7332
 
7333
								}
7334
 
7335
						}
7336
 
7337
					}
7338
 
7339
			}
7340
 
7341
				doeaxfloatmath(tk_fpust);
7342
 
7343
				next=0;
7344
 
7345
				CheckAllMassiv(wbuf,razr,&wstr,&wtok);
7346
 
7347
				op(0xd8+addop);
7348
 
7349
				outaddress(&wtok);
7350
 
7351
					outseg(&wtok,2);	//fstp var
7352
 
7353
					op(wtok.rm+0x18);
7354
 
7355
					fwait3();
7356
 
7357
			}
7358
 
7359
				switch(tok){
7360
 
7361
						if(rettype==tk_float){
7362
 
7363
							else if(itok.rm!=tk_float){
7364
 
7365
								*(float *)&itok.number=temp;
7366
 
7367
						}
7368
 
7369
							if(itok.rm==tk_float)itok.dnumber=itok.fnumber;
7370
 
7371
						}
7372
 
7373
						if(vop==0x38){	// div 22.12.05 22:10
7374
 
7375
							if(itok.rm==tk_float)itok.fnumber=1/itok.fnumber;
7376
 
7377
						}
7378
 
7379
						op66(r32);
7380
 
7381
						op((am32==FALSE?0x06:0x05));	//fld
7382
 
7383
						outword(0);
7384
 
7385
						CheckAllMassiv(wbuf,razr,&wstr,&wtok);
7386
 
7387
						op(0xd8+addop);
7388
 
7389
						outaddress(&wtok);
7390
 
7391
							outseg(&wtok,2);	//fstp var
7392
 
7393
							op(wtok.rm+0x18);
7394
 
7395
							fwait3();
7396
 
7397
						break;
7398
 
7399
						sign=2;
7400
 
7401
						CheckAllMassiv(bufrm,4,&strinf);
7402
 
7403
						op(0xd9+sign);
7404
 
7405
						outaddress(&itok);
7406
 
7407
					case tk_qwordvar:
7408
 
7409
						i=0x28;
7410
 
7411
						CheckAllMassiv(bufrm,8,&strinf);
7412
 
7413
						op(0xdd+sign);
7414
 
7415
						outaddress(&itok);
7416
 
7417
					case tk_dwordvar:
7418
 
7419
						op66(r32); 		//push 0L
7420
 
7421
						if(ESPloc&&am32&&itok.segm==SS)itok.number+=4;
7422
 
7423
						CheckAllMassiv(bufrm,4,&strinf);
7424
 
7425
						outseg(&itok,2);
7426
 
7427
						op(itok.rm+0x30);
7428
 
7429
						if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4;
7430
 
7431
						fildq_stack();
7432
 
7433
						outseg(&wtok,2);	//fsubr var
7434
 
7435
						op(wtok.rm+vop);
7436
 
7437
						if(optimizespeed||am32==0){
7438
 
7439
							op(8);
7440
 
7441
						else{
7442
 
7443
							op(0x58);	// pop EAX
7444
 
7445
						addESP-=8;
7446
 
7447
							outseg(&wtok,2);	//fstp var
7448
 
7449
							op(wtok.rm+0x18);
7450
 
7451
							fwait3();
7452
 
7453
						RestoreBP();
7454
 
7455
					case tk_reg32:	//добавить обработку интерпритации float, long
7456
 
7457
						op66(r32);	//push 0L
7458
 
7459
						op66(r32);  //push reg32
7460
 
7461
						if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8;
7462
 
7463
						fildq_stack();
7464
 
7465
						outseg(&wtok,2);	//fsubr var
7466
 
7467
						op(wtok.rm+vop);
7468
 
7469
						if(optimizespeed||am32==0){
7470
 
7471
							op(8);
7472
 
7473
						else{
7474
 
7475
							op(0x58);	// pop EAX
7476
 
7477
						addESP-=8;
7478
 
7479
							outseg(&wtok,2);	//fstp var
7480
 
7481
							op(wtok.rm+0x18);
7482
 
7483
							fwait3();
7484
 
7485
						RestoreBP();
7486
 
7487
					default:
7488
 
7489
							CheckInitBP();
7490
 
7491
							op(0x50);
7492
 
7493
							fld_stack(4+localsize);
7494
 
7495
							RestoreBP();
7496
 
7497
							op(0x58);
7498
 
7499
						goto endequals;
7500
 
7501
			}
7502
 
7503
		case tk_swap:
7504
 
7505
			regdi=TRUE;
7506
 
7507
			rbuf=bufrm;
7508
 
7509
			if(am32!=FALSE&&wbuf!=NULL&&wstr.bufstr!=NULL)regdi=FALSE;
7510
 
7511
				case tk_reg32:	//добавить обработку интерпритации float, long
7512
 
7513
					op66(r32);   		//push 0L
7514
 
7515
					op66(r32);     //push reg32
7516
 
7517
					if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8;
7518
 
7519
					fildq_stack();
7520
 
7521
					outseg(&wtok,2);	//fld val
7522
 
7523
					op(wtok.rm);
7524
 
7525
					op(0xdb);
7526
 
7527
						if(optimizespeed)outword(0x241c);	//fistp ssdword[bp-8]/ssdword[esp]
7528
 
7529
							outword(0x245C);
7530
 
7531
						}
7532
 
7533
					else{
7534
 
7535
						dob=8;
7536
 
7537
						if(short_ok(localsize+dob,FALSE)==0){
7538
 
7539
							outword(-dob-localsize);
7540
 
7541
						else{
7542
 
7543
							op(-dob-localsize);
7544
 
7545
					}
7546
 
7547
					op(0xd9+addop);
7548
 
7549
					outaddress(&wtok);
7550
 
7551
					op66(r32);     // pop reg32
7552
 
7553
					if(!optimizespeed){
7554
 
7555
					  op(0x58+(unsigned int)itok.number);
7556
 
7557
					else{
7558
 
7559
						op(4);
7560
 
7561
					addESP-=8;
7562
 
7563
					break;
7564
 
7565
					CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]);
7566
 
7567
					op(0xDB);
7568
 
7569
					outaddress(&itok);
7570
 
7571
					outseg(&wtok,2);	//fld val
7572
 
7573
					op(wtok.rm);
7574
 
7575
					outseg(&itok,2);//fistp var
7576
 
7577
					op(itok.rm+0x18);
7578
 
7579
					outseg(&wtok,2);	//fstp val
7580
 
7581
					op(wtok.rm+0x18);
7582
 
7583
					fwait3();
7584
 
7585
				case tk_qwordvar:
7586
 
7587
					outseg(&itok,2);	//fildq val
7588
 
7589
					op(itok.rm+0x28);
7590
 
7591
					CheckAllMassiv(wbuf,razr,&wstr,&wtok);
7592
 
7593
					op(0xd9+addop);
7594
 
7595
					outaddress(&wtok);
7596
 
7597
					op(0xdf);
7598
 
7599
					outaddress(&itok);
7600
 
7601
					op(0xd9+addop);
7602
 
7603
					outaddress(&wtok);
7604
 
7605
					break;
7606
 
7607
					CheckInitBP();
7608
 
7609
					outword(0x6a);
7610
 
7611
					addESP+=4;
7612
 
7613
					op66(r32);	//push var
7614
 
7615
					op(0xFF);
7616
 
7617
					outaddress(&itok);
7618
 
7619
					addESP+=4;
7620
 
7621
					CheckAllMassiv(wbuf,razr,&wstr,&wtok);
7622
 
7623
					op(0xd9+addop);
7624
 
7625
					outaddress(&wtok);
7626
 
7627
						outword(0xC483);
7628
 
7629
					}
7630
 
7631
						op(0x58);	// pop EAX
7632
 
7633
					}
7634
 
7635
					outseg(&itok,2);//fistp var
7636
 
7637
					op(itok.rm+0x18);
7638
 
7639
					outseg(&wtok,2);	//fstp val
7640
 
7641
					op(wtok.rm+0x18);
7642
 
7643
					fwait3();
7644
 
7645
					break;
7646
 
7647
					if(rettype==tk_double){
7648
 
7649
						outseg(&itok,2);	//fld val
7650
 
7651
						op(itok.rm);
7652
 
7653
						CheckAllMassiv(wbuf,8,&wstr,&wtok);
7654
 
7655
						op(0xdd);
7656
 
7657
						outaddress(&wtok);
7658
 
7659
						op(0xd9);
7660
 
7661
						outaddress(&itok);
7662
 
7663
						op(0xdd);
7664
 
7665
						outaddress(&wtok);
7666
 
7667
					}
7668
 
7669
						getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32);
7670
 
7671
						op66(r32);
7672
 
7673
						op(0x87); op(itok.rm);
7674
 
7675
						goto getfromeax;
7676
 
7677
					break;
7678
 
7679
					if(rettype==tk_float){
7680
 
7681
						outseg(&itok,2);	//fldq val
7682
 
7683
						op(itok.rm);
7684
 
7685
						CheckAllMassiv(wbuf,8,&wstr,&wtok);
7686
 
7687
						op(0xd9);
7688
 
7689
						outaddress(&wtok);
7690
 
7691
						op(0xdd);
7692
 
7693
						outaddress(&itok);
7694
 
7695
						op(0xd9);
7696
 
7697
						outaddress(&wtok);
7698
 
7699
					}
7700
 
7701
						getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32);
7702
 
7703
						op66(r32);
7704
 
7705
						op(0x87); op(itok.rm);
7706
 
7707
						goto getfromeax;
7708
 
7709
					break;
7710
 
7711
					if(itok.number>6)fpustdestroed();
7712
 
7713
					outseg(&wtok,2);	//fld val
7714
 
7715
					op(wtok.rm);
7716
 
7717
					op(0xD9);
7718
 
7719
					outseg(&wtok,2);	//fstp val
7720
 
7721
					op(wtok.rm+0x18);
7722
 
7723
					break;
7724
 
7725
			}
7726
 
7727
		default: operatorexpected(); break;
7728
 
7729
	if(next)nexttok();
7730
 
7731
	if(cpu<3)cpu=3;
7732
 
7733
}
7734
 
7735
void fildq2_stack(int size)
7736
 
7737
	op(0xdf);
7738
 
7739
	else{
7740
 
7741
			op(0xAE);
7742
 
7743
		}
7744
 
7745
			op(0x6E);
7746
 
7747
		}
7748
 
7749
}
7750
 
7751
void fildq_stack()
7752
 
7753
	fildq2_stack(localsize+8);
7754
 
7755
7756
 
7757
{
7758
 
7759
	else{
7760
 
7761
			op(0x9E);
7762
 
7763
		}
7764
 
7765
			op(0x5E);
7766
 
7767
		}
7768
 
7769
}
7770
 
7771
void fistp_stack(int addop)
7772
 
7773
	op(0xDB+addop);
7774
 
7775
}
7776
 
7777
void fld_stack(int size)
7778
 
7779
	if(am32)outword(0x2404);	//fld ssdword[ebp+2]/ssdword[esp]
7780
 
7781
		if(short_ok(size,FALSE)==0){
7782
 
7783
			outword(-size);
7784
 
7785
		else{
7786
 
7787
			op(-size);
7788
 
7789
	}
7790
 
7791
7792
 
7793
//конвертация float в число
7794
 
7795
	CheckInitBP();
7796
 
7797
	fld_stack(4+localsize+addop);
7798
 
7799
	RestoreBP();
7800
 
7801
	op66(r32);
7802
 
7803
	if(cpu<3)cpu=3;
7804
 
7805
7806
 
7807
{
7808
 
7809
	op66(r32);
7810
 
7811
	if(ESPloc&&am32&&itok.segm==SS)itok.number+=4;
7812
 
7813
	CheckAllMassiv(bufrm,4+addop,&strinf,&itok,reg1,reg2);
7814
 
7815
	op(0xd9+addop);
7816
 
7817
	outaddress(&itok);
7818
 
7819
	fwait3();
7820
 
7821
	op(0x58+reg);	//pop reg
7822
 
7823
	if(cpu<3)cpu=3;
7824
 
7825
}
7826
 
7827
void  byteinstack(int *numstak,int *nums)
7828
 
7829
	CheckInitBP();
7830
 
7831
	op66(r16);
7832
 
7833
		outword(0xC031);	//xor ax,ax
7834
 
7835
		op(0x8A);
7836
 
7837
	else{
7838
 
7839
		op(0xf);
7840
 
7841
		else op(0xbe);
7842
 
7843
	op(itok.rm);
7844
 
7845
	op66(r16);
7846
 
7847
	*numstak+=2;
7848
 
7849
	fld_stack(*nums+*numstak);
7850
 
7851
7852
 
7853
{
7854
 
7855
	op66(tok==tk_reg32?r32:r16);
7856
 
7857
		if(optimizespeed&&chip>3&&chip<7&&itok.number!=AL&&itok.number!=AH){
7858
 
7859
			op(0x88);
7860
 
7861
		}
7862
 
7863
		else{
7864
 
7865
			op(0xC0+itok.number);
7866
 
7867
		itok.number=0;
7868
 
7869
	else outword(0x6a);  //push 0
7870
 
7871
	op(0x50+itok.number);	//push AX
7872
 
7873
		op(0xDB);
7874
 
7875
		addESP+=4;
7876
 
7877
	}
7878
 
7879
		op(0xdf);
7880
 
7881
		addESP+=2;
7882
 
7883
	}
7884
 
7885
		*numstak+=8;
7886
 
7887
		fildq2_stack(*nums+*numstak);
7888
 
7889
}
7890
 
7891
void wordinstack(int *numstak,int *nums)
7892
 
7893
	CheckInitBP();
7894
 
7895
	outword(0x6a);  //push 0
7896
 
7897
	CheckAllMassiv(bufrm,tok==tk_wordvar?2:4,&strinf);
7898
 
7899
	outseg(&itok,2); //push var
7900
 
7901
	op(itok.rm+0x30);
7902
 
7903
	if(tok==tk_wordvar){
7904
 
7905
		addESP+=4;
7906
 
7907
		fld_stack(*nums+*numstak);
7908
 
7909
	else{
7910
 
7911
		*numstak+=8;
7912
 
7913
	}
7914
 
7915
7916
 
7917
{
7918
 
7919
	outseg(&itok,2);	//fild intvar
7920
 
7921
	else if(tok==tk_floatvar||tok==tk_doublevar)op(0xd9+addop);
7922
 
7923
	op(itok.rm+(tok==tk_qwordvar?0x28:0));
7924
 
7925
}
7926
 
7927
int doeaxfloatmath(int itreturn,int reg,int addop)
7928
 
7929
int vop,negflag=0,next,numstak=0;
7930
 
7931
int i=0;
7932
 
7933
int ols;
7934
 
7935
	nums+=localsize;
7936
 
7937
	if(tok==tk_minus){
7938
 
7939
			negflag=1;
7940
 
7941
		}
7942
 
7943
	if(tok==tk_number){
7944
 
7945
		if(addop==0/*itok.rm==tk_float*/){
7946
 
7947
			itok.rm=tk_float;
7948
 
7949
		else{
7950
 
7951
			itok.rm=tk_double;
7952
 
7953
		next=0;
7954
 
7955
//			if(itok.rm==tk_float&&addop==4)itok.dnumber=itok.fnumber;
7956
 
7957
			if(itreturn==tk_stackstart){
7958
 
7959
					lnumber=itok.lnumber;
7960
 
7961
				}
7962
 
7963
					op66(r32);
7964
 
7965
						op(0x6A);
7966
 
7967
					}
7968
 
7969
						op(0x68);
7970
 
7971
					}
7972
 
7973
					if(i==1)break;
7974
 
7975
				}
7976
 
7977
			}
7978
 
7979
				MovRegNum(r32,0,itok.number,reg);
7980
 
7981
			}
7982
 
7983
				MovRegNum(r32,0,itok.number,reg&255);
7984
 
7985
				return itreturn;
7986
 
7987
		}
7988
 
7989
	if(itreturn==tk_stackstart&&(!am32)){
7990
 
7991
		op(0x50);	//push eax
7992
 
7993
			op66(r32);
7994
 
7995
		}
7996
 
7997
		outword(0xe589);//mov bp,sp
7998
 
7999
		localsize=-6-addop;
8000
 
8001
	if(next==0)goto casenumber;
8002
 
8003
		case tk_number:
8004
 
8005
//		printf("rm=%d %e %e %08X\n",itok.rm,itok.fnumber,itok.dnumber,itok.number);
8006
 
8007
					(itok.rm==tk_double&&itok.dnumber==1.0)||
8008
 
8009
				outword(0xE8D9);	//FLD1
8010
 
8011
			}
8012
 
8013
					(itok.rm==tk_double&&itok.dnumber==0.0)||itok.lnumber==0){
8014
 
8015
				break;
8016
 
8017
			op(0xD9+(itok.rm==tk_float?0:4));
8018
 
8019
			AddFloatConst(itok.lnumber,itok.rm);
8020
 
8021
			if(am32)outword(0);
8022
 
8023
		case tk_at:
8024
 
8025
			macros(tk_fpust);
8026
 
8027
		case tk_ID:
8028
 
8029
		case tk_proc:
8030
 
8031
		case tk_declare:
8032
 
8033
int onums;
8034
 
8035
			nums=-(int)localsize;
8036
 
8037
			nums=onums;
8038
 
8039
				nexttok();
8040
 
8041
			}
8042
 
8043
		case tk_qwordvar:
8044
 
8045
			i=4;
8046
 
8047
		case tk_longvar:
8048
 
8049
			intinstack(i);
8050
 
8051
		case tk_dwordvar:
8052
 
8053
			wordinstack(&numstak,&nums);
8054
 
8055
		case tk_charvar:
8056
 
8057
			byteinstack(&numstak,&nums);
8058
 
8059
		case tk_beg:
8060
 
8061
		case tk_reg:
8062
 
8063
			break;
8064
 
8065
			if(itok.number){
8066
 
8067
				op(0xC8+itok.number);
8068
 
8069
			break;
8070
 
8071
	}
8072
 
8073
		outword(0xe0d9);	//fchs
8074
 
8075
	}
8076
 
8077
	while(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){
8078
 
8079
		vop=0;
8080
 
8081
		switch(tok){
8082
 
8083
			case tk_divminus: negflag=1;
8084
 
8085
			case tk_minus: vop+=0x20;
8086
 
8087
			case tk_mult: vop+=8;
8088
 
8089
 
8090
 
8091
					case tk_number:
8092
 
8093
							itok.dnumber=itok.lnumber;
8094
 
8095
						}
8096
 
8097
								(itok.rm==tk_double&&itok.dnumber==1.0)){
8098
 
8099
							if(vop==0||vop==0x28){	// + -
8100
 
8101
								op(0xDE);
8102
 
8103
							}
8104
 
8105
						}
8106
 
8107
8108
 
8109
							vop=8;	//mult
8110
 
8111
							else itok.dnumber=1/itok.dnumber;
8112
 
8113
						if(/*vop==0x38||*/vop==0x28)vop-=8;
8114
 
8115
						op((am32==FALSE?0x06:0x05)+vop);
8116
 
8117
						outword(0);
8118
 
8119
						break;
8120
 
8121
						i=4;
8122
 
8123
						if(vop==0x38||vop==0x28)vop-=8;
8124
 
8125
						outseg(&itok,2);	//fsubr var
8126
 
8127
						op(itok.rm+vop);
8128
 
8129
						break;
8130
 
8131
					case tk_intvar:
8132
 
8133
						outseg(&itok,2);	//fsubr var
8134
 
8135
						if(vop==0x38||vop==0x28)vop-=8;
8136
 
8137
						outaddress(&itok);
8138
 
8139
					case tk_qwordvar:
8140
 
8141
						op(0xde);
8142
 
8143
						break;
8144
 
8145
					case tk_wordvar:
8146
 
8147
						op(0xde);
8148
 
8149
						break;
8150
 
8151
					case tk_reg32:
8152
 
8153
						reginstack(&numstak,&nums);
8154
 
8155
						op(0xC1+vop);//fsubpr st1
8156
 
8157
					case tk_charvar:
8158
 
8159
						byteinstack(&numstak,&nums);
8160
 
8161
						op(0xC1+vop);//fsubpr st1
8162
 
8163
					case tk_fpust:
8164
 
8165
						op(0xd8);
8166
 
8167
						break;
8168
 
8169
				}
8170
 
8171
			default: illegalfloat(); break;
8172
 
8173
		if(negflag){
8174
 
8175
			negflag=0;
8176
 
8177
		if(next)nexttok();
8178
 
8179
	if(tok==tk_eof)unexpectedeof();
8180
 
8181
		if(!am32){
8182
 
8183
			outword(0x025e);	//fstp ssdword[bp+2]
8184
 
8185
		}
8186
 
8187
			if(numstak<4){
8188
 
8189
				op(0x50);	//push eax
8190
 
8191
			}
8192
 
8193
			if(addop){
8194
 
8195
					op66(r32);
8196
 
8197
					addESP+=4;
8198
 
8199
				else numstak-=4;
8200
 
8201
			op(0xD9+addop);
8202
 
8203
			else{
8204
 
8205
				op(numstak);
8206
 
8207
		}
8208
 
8209
	}
8210
 
8211
		i=4;
8212
 
8213
		if(numstak
8214
 
8215
			op(0x50);	//push eax
8216
 
8217
				op66(r32);
8218
 
8219
			}
8220
 
8221
			addESP+=i;
8222
 
8223
		op(itreturn==tk_reg32?0xDB:0xDF);
8224
 
8225
		fistp2_stack(localsize+numstak);
8226
 
8227
		if(itreturn==tk_reg64){
8228
 
8229
			op(0x58);	//pop EAX
8230
 
8231
			op(0x58+EDX);	//pop EDX
8232
 
8233
		else{
8234
 
8235
			op(0x58+reg);	//pop reg
8236
 
8237
		numstak-=i;
8238
 
8239
	}
8240
 
8241
		localsize=ols;
8242
 
8243
		initBP--;
8244
 
8245
	else if(numstak){
8246
 
8247
			outword(0xC483);
8248
 
8249
		}
8250
 
8251
			outword(0xC481);
8252
 
8253
		}
8254
 
8255
	}
8256
 
8257
	nums-=localsize;
8258
 
8259
}
8260
 
8261
void float2stack(int num)
8262
 
8263
	outword(0xC0DD);
8264
 
8265
//	if(num>6)fpustdestroed();
8266
 
8267
	doeaxfloatmath(tk_fpust);
8268
 
8269
		op(0xD9);
8270
 
8271
	}
8272
 
8273
8274
 
8275
{
8276
 
8277
	nexttok();
8278
 
8279
		case tk_assign:	//=
8280
 
8281
			float2stack(num);
8282
 
8283
		case tk_divequals: vop+=0x10;
8284
 
8285
		case tk_multequals: vop+=8;
8286
 
8287
			getoperand(am32==TRUE?EAX:BX);
8288
 
8289
//			doeaxfloatmath(tk_fpust);
8290
 
8291
			op(0xC0+vop+num);//fsubpr st
8292
 
8293
		case tk_swap:
8294
 
8295
			switch(tok){
8296
 
8297
					op(0xD9);
8298
 
8299
					op(0xD9);
8300
 
8301
					op(0xD9);
8302
 
8303
					break;
8304
 
8305
					vop=4;
8306
 
8307
					CheckAllMassiv(bufrm,4,&strinf);
8308
 
8309
					op(0xd9+vop);
8310
 
8311
					outaddress(&itok);
8312
 
8313
					op(0xC8+num+1);
8314
 
8315
					op(0xd9+vop);
8316
 
8317
					outaddress(&itok);
8318
 
8319
				default:
8320
 
8321
					break;
8322
 
8323
 
8324
 
8325
		default:
8326
 
8327
	}
8328
 
8329
8330
 
8331
{
8332
 
8333
		Leave();
8334
 
8335
	}
8336
 
8337
8338
 
8339
{
8340
 
8341
		op(0x55);       //push bp
8342
 
8343
		initBP=2;
8344
 
8345
}
8346
 
8347
void AddReloc(int segm)
8348
 
8349
	if(FixUp!=FALSE){
8350
 
8351
		if(segm==DS){
8352
 
8353
			(postbuf+posts)->loc=outptrdata;
8354
 
8355
		else{
8356
 
8357
			(postbuf+posts)->loc=outptr;
8358
 
8359
		posts++;
8360
 
8361
	postnumflag&=(~f_reloc);
8362
 
8363
8364
 
8365
{
8366
 
8367
}
8368
 
8369
void AddFloatConst(long long fnumber,int type)
8370
 
8371
unsigned int i;
8372
 
8373
	for(i=0;i
8374
 
8375
			ofs=(floatnum+i)->ofs;
8376
 
8377
				if(*(long *)&fnumber==(floatnum+i)->num[0])goto endp;
8378
 
8379
			else if(*(double *)&fnumber==(floatnum+i)->dnum)goto endp;
8380
 
8381
	}
8382
 
8383
		floatnum=(LISTFLOAT *)MALLOC(sizeof(LISTFLOAT)*STEPFLOATCONST);
8384
 
8385
//		memset(floatnum,0,sizeof(LISTFLOAT)*STEPFLOATCONST);
8386
 
8387
	else if((numfloatconst+1)==maxnumfloatconst){
8388
 
8389
		maxnumfloatconst+=STEPFLOATCONST;
8390
 
8391
	numfloatconst++;
8392
 
8393
	ofs=(floatnum+i)->ofs=ofsfloatlist;
8394
 
8395
	else (floatnum+i)->dnum=*(double *)&fnumber;
8396
 
8397
endp:
8398
 
8399
	(postbuf+posts)->type=POST_FLOATNUM;
8400
 
8401
	(postbuf+posts)->num=ofs;
8402
 
8403
}
8404
 
8405
void setwordext(long *id)
8406
 
8407
	CheckPosts();
8408
 
8409
	(postbuf+posts)->loc=outptr;
8410
 
8411
	*id>>=16;	//ее значение
8412
 
8413
}
8414
 
8415
void setwordpost(ITOK *stok)						/* for post word num setting */
8416
 
8417
	CheckPosts();
8418
 
8419
		(postbuf+posts)->type=(unsigned short)(am32==0?DIN_VAR:DIN_VAR32);
8420
 
8421
//		printf("rec=%08X\n",stok->rec);
8422
 
8423
			(postbuf+posts)->num=(int)stok->rec;//02.09.05 17:11 ->right;
8424
 
8425
		else (postbuf+posts)->num=(int)stok->rec;
8426
 
8427
	else if(stok->post>=CODE_SIZE&&stok->post<=STACK_SIZE32)(postbuf+posts)->type=stok->post;
8428
 
8429
	(postbuf+posts)->loc=outptr;
8430
 
8431
}
8432
 
8433
void MovRegNum(int razr,int relocf,unsigned long number,int reg)
8434
 
8435
unsigned long num;
8436
 
8437
	op66(razr);
8438
 
8439
		if(number!=0&&GetRegNumber(reg,&num,razr)==reg){
8440
 
8441
			if(num==number)return;
8442
 
8443
				num=number-num;
8444
 
8445
					op(0x40+reg);	//inc reg
8446
 
8447
				}
8448
 
8449
					op(0x40+reg);	//inc reg
8450
 
8451
					op(0x40+reg);	//inc reg
8452
 
8453
				}
8454
 
8455
					op(0x83);
8456
 
8457
 
8458
 
8459
				}
8460
 
8461
			else{
8462
 
8463
				if(num==1){
8464
 
8465
					return;
8466
 
8467
				if(num==2){
8468
 
8469
					op66(razr);
8470
 
8471
					return;
8472
 
8473
				if(razr==r32&&short_ok(num,TRUE)){
8474
 
8475
					op(0xE8+reg);
8476
 
8477
					return;
8478
 
8479
			}
8480
 
8481
		if((nreg=GetNumberR(reg,&num,razr,number))!=NOINREG){
8482
 
8483
			if(num==number){
8484
 
8485
				op(128+64+nreg*8+reg);
8486
 
8487
			}
8488
 
8489
				op(0x89);
8490
 
8491
				op66(razr);
8492
 
8493
				return;
8494
 
8495
			else{
8496
 
8497
					op(0x89);
8498
 
8499
					op66(razr);
8500
 
8501
					return;
8502
 
8503
			}
8504
 
8505
		ConstToReg(number,reg,razr);
8506
 
8507
			op(0x31); op(0xC0+reg*9);
8508
 
8509
		else if((long)number==-1&&razr==r32){
8510
 
8511
			op(0xC8+reg);
8512
 
8513
		}
8514
 
8515
			op(0x31); op(0xC0+reg*9);	//xor reg,reg
8516
 
8517
			op(0x40+reg);	//inc reg
8518
 
8519
		else if(regoverstack&&razr==r32&&short_ok(number,TRUE)){
8520
 
8521
			op(number);	//push short number
8522
 
8523
		  op(0x58+reg);
8524
 
8525
		else goto stdmov;
8526
 
8527
	else{
8528
 
8529
		op(0xB8+reg);	// MOV reg,#
8530
 
8531
		razr==r16?outword(number):outdword(number);
8532
 
8533
	}
8534
 
8535
8536
 
8537
{
8538
 
8539
	if(optimizespeed&&(chip==5||chip==6)){
8540
 
8541
		op(0xF0+reg);
8542
 
8543
		op66(razr);
8544
 
8545
	}
8546
 
8547
		op(0xF7);
8548
 
8549
	}
8550
 
8551
}
8552
 
8553
int RshiftReg(int razr,int reg,int sign)
8554
 
8555
char *ofsstr=NULL;
8556
 
8557
		if((unsigned int)itok.number==1){
8558
 
8559
			op(0xD1); op(0xE8+reg+sign);  // SHR reg,1
8560
 
8561
		else if((unsigned int)itok.number!=0){
8562
 
8563
				if(reg==ECX)return FALSE;
8564
 
8565
			}
8566
 
8567
				op66(razr);
8568
 
8569
				op(0xe8+reg+sign); // SHR reg,imm8
8570
 
8571
				if(cpu<2)cpu=2;
8572
 
8573
		}
8574
 
8575
	}
8576
 
8577
	else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==CL){
8578
 
8579
		goto rshift;
8580
 
8581
	else{
8582
 
8583
		getintobeg(CL,&ofsstr);
8584
 
8585
rshift:
8586
 
8587
		op(0xD3);
8588
 
8589
	}
8590
 
8591
}
8592
 
8593
int CheckMinusNum()
8594
 
8595
	if(tok==tk_minus&&tok2==tk_number){
8596
 
8597
		if(itok.rm==tk_float)itok.number|=0x80000000;
8598
 
8599
		else itok.lnumber=-itok.lnumber;
8600
 
8601
	}
8602
 
8603
}
8604
 
8605
int MulReg(int reg,int razr)
8606
 
8607
int next=1,i=0;
8608
 
8609
char *ofsstr=NULL;
8610
 
8611
		case tk_number:
8612
 
8613
			break;
8614
 
8615
		case tk_undefofs:
8616
 
8617
			op66(razr);
8618
 
8619
			op(0xc0+reg*9);
8620
 
8621
			else AddUndefOff(0,itok.name);
8622
 
8623
			break;
8624
 
8625
			if(chip<2&&razr==r16)regmathoperror();
8626
 
8627
			op(0x69);
8628
 
8629
			AddApiToPost(itok.number);
8630
 
8631
		case tk_doublevar:
8632
 
8633
		case tk_floatvar:
8634
 
8635
			Float2reg32(i,ii);
8636
 
8637
			outword(0xAF0F);
8638
 
8639
			warningreg(regs[1][i]);
8640
 
8641
		case tk_qwordvar:
8642
 
8643
		case tk_longvar:
8644
 
8645
			i+=4;
8646
 
8647
		case tk_intvar:
8648
 
8649
			if(chip<2)regmathoperror();
8650
 
8651
			i=2;
8652
 
8653
			CheckAllMassiv(bufrm,i,&strinf);
8654
 
8655
			outseg(&itok,3);
8656
 
8657
			op(reg*8+itok.rm);
8658
 
8659
			break;
8660
 
8661
			int vops,reg2s;
8662
 
8663
			if(i<=64)vops=r64;
8664
 
8665
			if(i<=16)vops=r16;
8666
 
8667
			reg2s=CX;
8668
 
8669
			bits2reg(reg2s,vops);
8670
 
8671
			warningreg(regs[vops/2-1][reg2s]);
8672
 
8673
			goto defreg32;
8674
 
8675
			if(chip<2)regmathoperror();
8676
 
8677
				op66(r32);
8678
 
8679
				if(itok.number==reg){
8680
 
8681
					itok.number=EAX;
8682
 
8683
				else op(0xC0+itok.number*9);
8684
 
8685
			}
8686
 
8687
defreg32:
8688
 
8689
			outword(0xAF0F);
8690
 
8691
			break;
8692
 
8693
		case tk_id:
8694
 
8695
		case tk_apiproc:
8696
 
8697
		case tk_declare:
8698
 
8699
			i=EAX;
8700
 
8701
		case tk_seg:
8702
 
8703
		case tk_beg:
8704
 
8705
		case tk_rmnumber:
8706
 
8707
			i=EDX;
8708
 
8709
			getintoreg_32(i,razr,0,&ofsstr,FALSE);
8710
 
8711
		 	op66(razr);
8712
 
8713
			op(0xC0+reg*8+i);
8714
 
8715
			if(i!=EDX)warningreg(regs[razr/2-1][i]);
8716
 
8717
			break;
8718
 
8719
	}
8720
 
8721
}
8722
 
8723
void DivMod(int vop,int sign,int razr,int expand)
8724
 
8725
int i,next;
8726
 
8727
	if(tok==tk_bits){
8728
 
8729
		if(i<=64)next=r64;
8730
 
8731
		if(i<=16)next=r16;
8732
 
8733
		itok.number=CX;
8734
 
8735
		ClearReg(CX);
8736
 
8737
		tok=(razr==r16?tk_reg:tk_reg32);
8738
 
8739
	i=0;
8740
 
8741
	if(tok==tk_number){
8742
 
8743
		if(vop){	//%
8744
 
8745
			if(itok.number==0)DevideZero();
8746
 
8747
				itok.number--;
8748
 
8749
 				else if(short_ok(itok.number,razr/2-1)){
8750
 
8751
					outword(0xE083);
8752
 
8753
				}
8754
 
8755
					op66(razr);
8756
 
8757
					razr==r16?outword((unsigned int)itok.number):outdword(itok.number);
8758
 
8759
				setzeroflag=TRUE;
8760
 
8761
			else{
8762
 
8763
				if(!expand)ClearDX(razr,sign);
8764
 
8765
				setzeroflag=FALSE;
8766
 
8767
		}
8768
 
8769
			if((itok.flag&f_reloc)!=0)goto divin;
8770
 
8771
				case 0:
8772
 
8773
					break;
8774
 
8775
				case 2:
8776
 
8777
						op66(razr);
8778
 
8779
							outdword(0x01d0ac0f);	//shrd ax,dx,1
8780
 
8781
						}
8782
 
8783
							outword(0xead1);	//shr dx,1 rcr ax,1
8784
 
8785
							outword(0xd8d1);
8786
 
8787
						}
8788
 
8789
						ClearReg(DX);
8790
 
8791
					}
8792
 
8793
				  if(sign)outword(0xF8D1);// SAR AX,1
8794
 
8795
					setzeroflag=TRUE;
8796
 
8797
					break;
8798
 
8799
					vop=caselong(itok.number);
8800
 
8801
						if(expand==TRUE){
8802
 
8803
								op66(razr);
8804
 
8805
								outword(0xd0ac);	//shrd ax,dx,vop
8806
 
8807
								setzeroflag=TRUE;
8808
 
8809
								ClearReg(DX);
8810
 
8811
							else{
8812
 
8813
								op(0xB1); op(vop); /* MOV CL,num */
8814
 
8815
								else outword(0xEad1); // SHR AX,1
8816
 
8817
								warningreg(begs[1]);
8818
 
8819
								ClearReg(AX);
8820
 
8821
							}
8822
 
8823
						else{
8824
 
8825
								op(0xB1); op(vop); /* MOV CL,num */
8826
 
8827
								else outword(0xE8D3); // SHR AX,CL
8828
 
8829
								ClearReg(AX);
8830
 
8831
							}
8832
 
8833
								op66(razr);
8834
 
8835
								else outword(0xE8C1); // SHR AX,num
8836
 
8837
								ClearReg(AX);
8838
 
8839
							setzeroflag=TRUE;
8840
 
8841
					}
8842
 
8843
						if(expand==FALSE)DivNum(itok.number,razr,sign);
8844
 
8845
divin:
8846
 
8847
							if(!expand)ClearDX(razr,sign);
8848
 
8849
						}
8850
 
8851
			}
8852
 
8853
	}
8854
 
8855
		if(tok==tk_doublevar){
8856
 
8857
			tok=tk_floatvar;
8858
 
8859
		if(tok==tk_floatvar){
8860
 
8861
			warningreg(regs[razr/2-1][1]);
8862
 
8863
			tok=(razr==r16?tk_reg:tk_reg32);
8864
 
8865
		}
8866
 
8867
			case tk_qwordvar:
8868
 
8869
			case tk_longvar:
8870
 
8871
				i+=2;
8872
 
8873
			case tk_wordvar:
8874
 
8875
				i+=2;
8876
 
8877
				if(expand==FALSE)ClearDX(razr,sign);
8878
 
8879
				outseg(&itok,2);
8880
 
8881
				if(sign)op(0x38+itok.rm); /* IDIV word ptr [#] */
8882
 
8883
				outaddress(&itok);
8884
 
8885
				break;
8886
 
8887
				if(razr==r32){
8888
 
8889
					getintoreg_32(i,r32,0,&ofsstr,FALSE);
8890
 
8891
					op66(r32);
8892
 
8893
					if(sign)op(0xF8+i);  /* IDIV ECX */
8894
 
8895
					next=0;
8896
 
8897
				ClearReg(AX);
8898
 
8899
					break;
8900
 
8901
			case tk_reg32:
8902
 
8903
		 		op66(razr);
8904
 
8905
				if(sign)op(0xF8+(unsigned int)itok.number);
8906
 
8907
				ClearReg(AX);
8908
 
8909
			case tk_ID:
8910
 
8911
			case tk_proc:
8912
 
8913
			case tk_undefproc:
8914
 
8915
				op66(razr);
8916
 
8917
				addESP+=razr==r16?2:4;
8918
 
8919
				oaddstack=addstack;
8920
 
8921
				procdo(razr==r16?(sign==0?tk_word:tk_int):(sign==0?tk_dword:tk_long));
8922
 
8923
				addESP-=razr==r16?2:4;
8924
 
8925
				op(0x90+ECX);	//xchg AX,CX
8926
 
8927
				op(0x58);	//pop AX
8928
 
8929
				op66(razr);
8930
 
8931
				if(sign)op(0xF8+ECX);  /* IDIV ECX */
8932
 
8933
				warningreg(regs[razr/2-1][ECX]);
8934
 
8935
			case tk_undefofs:
8936
 
8937
			case tk_charvar:
8938
 
8939
			case tk_bytevar:
8940
 
8941
			case tk_postnumber:
8942
 
8943
defdiv:
8944
 
8945
				if(expand==FALSE)ClearDX(razr,sign);
8946
 
8947
				if(sign)outword(0xF9F7);  /* IDIV CX */
8948
 
8949
				next=0;
8950
 
8951
				ClearReg(CX);
8952
 
8953
				break;
8954
 
8955
		}
8956
 
8957
/*		if(vop){
8958
 
8959
			if(optimizespeed)outword(0xC28B);	//mov ax,dx
8960
 
8961
		}*/
8962
 
8963
	if(next)nexttok();
8964
 
8965
8966
 
8967
{
8968
 
8969
unsigned long num2;
8970
 
8971
		if(razr==r16&&chip>2){
8972
 
8973
			if((65535/num2)!=num)goto stddiv;
8974
 
8975
			op(0x25);
8976
 
8977
			if(short_ok(num2,FALSE))i=2;	//короткая форма
8978
 
8979
			op(0x69+i);	//imul EAX,num
8980
 
8981
			if(i==2)op(num2);
8982
 
8983
		 	op66(r32);
8984
 
8985
			op(0x10);	//shr EAX,16
8986
 
8987
		}
8988
 
8989
			if(razr==r32)num=(unsigned long)0xFFFFFFFFL/num+1;
8990
 
8991
			op66(razr);
8992
 
8993
			if(razr==r16)outword(num);
8994
 
8995
			op66(razr);
8996
 
8997
			op66(razr);
8998
 
8999
			setzeroflag=FALSE;
9000
 
9001
		}
9002
 
9003
	}
9004
 
9005
	ClearDX(razr,sign);
9006
 
9007
}
9008
 
9009
void ClearDX(int razr,int sign)
9010
 
9011
	if(sign)cwdq(razr);
9012
 
9013
		op66(razr);
9014
 
9015
	}
9016
 
9017
	ClearReg(DX);
9018
 
9019
9020
 
9021
{
9022
 
9023
	op66(razr);
9024
 
9025
	else outword(0xF1F7); /* DIV CX */
9026
 
9027
	ClearReg(CX);
9028
 
9029
}
9030
 
9031
int getintoreg(int reg,int razr,int sign,char **ofsstr)
9032
 
9033
ITOK oitok,oitok2;
9034
 
9035
int oinptr,otok,otok2;
9036
 
9037
unsigned char ocha;
9038
 
9039
int operand=tk_plus;
9040
 
9041
char *obuf;
9042
 
9043
int i=0;
9044
 
9045
int onlynum=FALSE;
9046
 
9047
	switch(tok){
9048
 
9049
		case tk_id:
9050
 
9051
		case tk_apiproc:
9052
 
9053
		case tk_declare:
9054
 
9055
		default:
9056
 
9057
			obuf=bufrm;
9058
 
9059
			ostr=strinf;
9060
 
9061
			oitok=itok;
9062
 
9063
			otok=tok;
9064
 
9065
			oline=linenum2;
9066
 
9067
			oinput=input;
9068
 
9069
			bmod=cur_mod;
9070
 
9071
				bmod->freze=TRUE;
9072
 
9073
			}
9074
 
9075
			ocha=cha2;
9076
 
9077
			if(tok==tk_number)onlynum=TRUE;
9078
 
9079
				nexttok();
9080
 
9081
				if(itok.type==tp_opperand)operand=tok;
9082
 
9083
					i++;
9084
 
9085
					if(strinf.bufstr)free(strinf.bufstr);
9086
 
9087
						case tk_div:
9088
 
9089
						case tk_divminus:
9090
 
9091
							if(j==0)j=1;
9092
 
9093
							if(j==1){
9094
 
9095
									if(onlynum==FALSE&&caselong(itok.number)==NUMNUM)j++;
9096
 
9097
								else{
9098
 
9099
									onlynum=FALSE;
9100
 
9101
							}
9102
 
9103
					}
9104
 
9105
			}
9106
 
9107
				if(bmod&&bmod->freze){
9108
 
9109
					while(bmod){
9110
 
9111
						bmod=bmod->next;
9112
 
9113
				}
9114
 
9115
					do{
9116
 
9117
						cur_mod=cur_mod->next;
9118
 
9119
						if(temp->paramdef)free(temp->paramdef);
9120
 
9121
					}while(bmod!=cur_mod);
9122
 
9123
						bmod->freze=FALSE;
9124
 
9125
					}
9126
 
9127
				input=oinput;
9128
 
9129
			endinptr=oendinptr;
9130
 
9131
			itok2=oitok2;
9132
 
9133
			tok2=otok2;
9134
 
9135
			inptr2=oinptr;
9136
 
9137
			endoffile=0;
9138
 
9139
//			if(bufrm) { free(bufrm); bufrm=NULL; }
9140
 
9141
			bufrm=obuf;
9142
 
9143
			break;
9144
 
9145
	if(useeax){
9146
 
9147
		op(0x50);
9148
 
9149
		do_e_axmath(0,razr,ofsstr);
9150
 
9151
		if(optimizespeed){
9152
 
9153
			op(0xC0+reg);
9154
 
9155
		else op(0x90+reg);
9156
 
9157
		addESP-=razr==r16?2:4;
9158
 
9159
	}
9160
 
9161
		if(i==1&&j>=2){
9162
 
9163
			j=1;
9164
 
9165
		else i=reg;
9166
 
9167
		if(itok.type!=tp_stopper&&itok.type!=tp_compare&&tok!=tk_eof){
9168
 
9169
			rettype=tk_reg;
9170
 
9171
	}
9172
 
9173
}
9174
 
9175
void dobits()
9176
 
9177
ITOK wtok;
9178
 
9179
SINFO wstr;
9180
 
9181
unsigned int rettype;
9182
 
9183
char *ofsstr=NULL;
9184
 
9185
	razr=r32;
9186
 
9187
	if(i<9){
9188
 
9189
		posiblret=rettype=tk_byte;
9190
 
9191
	else if(i<17){
9192
 
9193
		razr=r16;
9194
 
9195
	else if(i>32)razr=r64;
9196
 
9197
		wstr=strinf;
9198
 
9199
		wtok=itok;
9200
 
9201
		bufrm=NULL;
9202
 
9203
		nexttok();
9204
 
9205
		while(tok==tk_mult){
9206
 
9207
			numpointr++;
9208
 
9209
		if(numpointr>itok.npointr)unuseableinput();
9210
 
9211
			MultiAssign(razr,EAX,numpointr);
9212
 
9213
		}
9214
 
9215
		CheckMinusNum();
9216
 
9217
			if(itok2.type==tp_opperand){	//сложное выражение
9218
 
9219
				itok.flag=(unsigned char)postnumflag;
9220
 
9221
			else{
9222
 
9223
				nexttok();
9224
 
9225
			}
9226
 
9227
			if(razr!=r64)num2bits(&wtok,itok.number,razr);
9228
 
9229
				int siz=wtok.bit.siz;
9230
 
9231
				num2bits(&wtok,itok.number,r32);
9232
 
9233
				wtok.bit.ofs=0;
9234
 
9235
				wtok.number+=4;
9236
 
9237
			}
9238
 
9239
		else{
9240
 
9241
			if(rettype==tk_char||rettype==tk_byte)doalmath(sign,&ofsstr);
9242
 
9243
			else if(rettype==tk_float)doeaxfloatmath(tk_reg32,AX);
9244
 
9245
			convert_returnvalue(posiblret,rettype);
9246
 
9247
axtobit:
9248
 
9249
			else{
9250
 
9251
				op66(r32);
9252
 
9253
				if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4;
9254
 
9255
				wtok.bit.siz=32-wtok.bit.ofs;
9256
 
9257
				op66(r32);
9258
 
9259
				addESP-=4;
9260
 
9261
				outword(0xE8C1);
9262
 
9263
				wtok.bit.siz=siz+wtok.bit.ofs-32;
9264
 
9265
				wtok.number+=4;
9266
 
9267
			}
9268
 
9269
		}
9270
 
9271
	else{
9272
 
9273
		wstr=strinf;
9274
 
9275
		wtok=itok;
9276
 
9277
		bufrm=NULL;
9278
 
9279
			case r8:
9280
 
9281
				break;
9282
 
9283
			case r32:
9284
 
9285
				break;
9286
 
9287
				doreg_32(AX,r32);
9288
 
9289
		}
9290
 
9291
	}
9292
 
9293
}
9294
 
9295
void bits2reg(int reg,int razr)
9296
 
9297
int i,j,skip66=FALSE;
9298
 
9299
	j=~GetBitMask(itok.bit.ofs,itok.bit.siz);
9300
 
9301
	char *wbuf;
9302
 
9303
	bufrm=NULL;
9304
 
9305
	SINFO wstr;
9306
 
9307
	strinf.bufstr=NULL;
9308
 
9309
		case r8:
9310
 
9311
				getintoal(tk_bytevar,&wtok,wbuf,&wstr);
9312
 
9313
					op(4+0x20);	//and al,j
9314
 
9315
				}
9316
 
9317
			else{
9318
 
9319
				outseg(&itok,2);
9320
 
9321
				op(reg*8+itok.rm);
9322
 
9323
				if(i!=8){
9324
 
9325
					op(128+64+reg+0x20);
9326
 
9327
				}
9328
 
9329
			if(itok.bit.ofs){	//shr al,ofs
9330
 
9331
					op(0xD0);
9332
 
9333
				}
9334
 
9335
					op(0xC0);
9336
 
9337
					op(itok.bit.ofs);
9338
 
9339
			}
9340
 
9341
		case r16:
9342
 
9343
			if(reg==AX){
9344
 
9345
				if(razr==r16&&i!=16){
9346
 
9347
					op(4+1+0x20);
9348
 
9349
				}
9350
 
9351
					op66(razr);	//and (e)ax,j
9352
 
9353
						op(128+2+1);
9354
 
9355
						op((int)j);
9356
 
9357
					else{
9358
 
9359
						outdword(j);
9360
 
9361
				}
9362
 
9363
				if(itok.bit.ofs){	//shr (e)ax,ofs
9364
 
9365
					if(itok.bit.ofs==1)outword(0xE8D1);
9366
 
9367
						outword(0xE8C1);
9368
 
9369
					}
9370
 
9371
			}
9372
 
9373
int reg1=idxregs[0],reg2=idxregs[1];
9374
 
9375
					if(reg==idxregs[2]||reg==idxregs[1]){
9376
 
9377
						if(reg==idxregs[1])reg2=idxregs[0];
9378
 
9379
				}
9380
 
9381
					reg1=reg;
9382
 
9383
				}
9384
 
9385
		 		op66(razr);
9386
 
9387
				op(0x8B);
9388
 
9389
				outaddress(&itok);
9390
 
9391
					op66(razr);	//and reg,j
9392
 
9393
						op(128+2+1);
9394
 
9395
						op(j);
9396
 
9397
					else{
9398
 
9399
						op(128+64+reg+0x20);
9400
 
9401
						else outdword(j);
9402
 
9403
				}
9404
 
9405
					op66(razr);
9406
 
9407
						op(0xD1);
9408
 
9409
					}
9410
 
9411
						op(0xC1);
9412
 
9413
						op(itok.bit.ofs);
9414
 
9415
				}
9416
 
9417
			break;
9418
 
9419
			if(reg==AX){
9420
 
9421
				itok.number+=4;
9422
 
9423
				op(0x8B);
9424
 
9425
				outaddress(&itok);
9426
 
9427
					op(128);
9428
 
9429
					op(li[itok.bit.siz+itok.bit.ofs-32]-1);
9430
 
9431
				op66(r32);
9432
 
9433
				op(0xC2);
9434
 
9435
				itok.number-=4;
9436
 
9437
			}
9438
 
9439
				int reg1=DX;
9440
 
9441
				CheckAllMassiv(bufrm,4,&strinf,&itok);
9442
 
9443
				outseg(&itok,2);
9444
 
9445
				op(reg*8+itok.rm);
9446
 
9447
				itok.number+=4;
9448
 
9449
				op(0x8B);
9450
 
9451
				outaddress(&itok);
9452
 
9453
					op(128+(reg1<4?0:3));
9454
 
9455
					op(li[itok.bit.siz+itok.bit.ofs-32]-1);
9456
 
9457
				itok.number-=4;
9458
 
9459
				outword(0xAC0F);	//shrd edx,eax,ofs
9460
 
9461
				op(itok.bit.ofs);
9462
 
9463
			}
9464
 
9465
			break;
9466
 
9467
	ClearReg(AX);
9468
 
9469
}
9470
 
9471
void num2bits(ITOK *gtok,unsigned long num,int razr)
9472
 
9473
unsigned int j,mask;
9474
 
9475
	j=li[gtok->bit.siz]-1;
9476
 
9477
		if(razr!=r8){
9478
 
9479
			outseg(gtok,2);
9480
 
9481
				op(128+2+1);
9482
 
9483
				outaddress(gtok);
9484
 
9485
			}
9486
 
9487
				op(128+1);
9488
 
9489
				outaddress(gtok);
9490
 
9491
				if(razr==r16)outword(mask);
9492
 
9493
			}
9494
 
9495
		else{
9496
 
9497
			op(128);
9498
 
9499
			outaddress(gtok);
9500
 
9501
		}
9502
 
9503
	num=(num&j)<bit.ofs; 	//or bits,mask
9504
 
9505
	if(num<256&&razr==r16)razr=r8;
9506
 
9507
		op66(razr);
9508
 
9509
		if((postnumflag&f_reloc)==0&&short_ok(num,razr/2-1)){
9510
 
9511
			op(gtok->rm+8);
9512
 
9513
			op(num);
9514
 
9515
		else{
9516
 
9517
			op(gtok->rm+8);
9518
 
9519
			if((postnumflag&f_reloc)!=0)AddReloc();
9520
 
9521
			else outdword(num);
9522
 
9523
	}
9524
 
9525
		if((unsigned char)num!=0){
9526
 
9527
			op(128);
9528
 
9529
			outaddress(gtok);
9530
 
9531
		}
9532
 
9533
}
9534
 
9535
void reg2bits(ITOK *gtok,int razr)
9536
 
9537
int i,j,mask;
9538
 
9539
	mask=GetBitMask(gtok->bit.ofs,gtok->bit.siz);
9540
 
9541
	switch(razr){
9542
 
9543
			if(i!=8){
9544
 
9545
				op(j);
9546
 
9547
			outseg(gtok,2);	//and bits,mask
9548
 
9549
			op(gtok->rm+0x20);
9550
 
9551
			op(mask);
9552
 
9553
			outseg(gtok,2);
9554
 
9555
			op(gtok->rm);
9556
 
9557
			break;
9558
 
9559
		case r32:
9560
 
9561
				op66(razr);	//and (e)ax,size
9562
 
9563
				outword(j);
9564
 
9565
			else if(razr==r32&&i!=32){
9566
 
9567
				if(short_ok(j,TRUE)){
9568
 
9569
					op(128+64+0x20);
9570
 
9571
				}
9572
 
9573
					op(4+1+0x20);
9574
 
9575
				}
9576
 
9577
			op66(razr);	//and bits,mask
9578
 
9579
			if(short_ok(mask,razr/2-1)){
9580
 
9581
				op(gtok->rm+0x20);
9582
 
9583
				op(mask);
9584
 
9585
			else{
9586
 
9587
				op(gtok->rm+0x20);
9588
 
9589
				if(razr==r16)outword(mask);
9590
 
9591
			}
9592
 
9593
			op66(razr);
9594
 
9595
			op(1+8);
9596
 
9597
			outaddress(gtok);
9598
 
9599
	}
9600
 
9601
9602
 
9603
{
9604
 
9605
	nexttok();
9606
 
9607
		nexttok();
9608
 
9609
	}
9610
 
9611
		unuseableinput();
9612
 
9613
	if(tok==tk_pointer){
9614
 
9615
	}
9616
 
9617
}
9618
 
9619
void cpointr(int reg,int numpointr)
9620
 
9621
	if(itok.type==tk_proc){
9622
 
9623
			tok=tk_proc;
9624
 
9625
		else{
9626
 
9627
			if(am32){
9628
 
9629
 
9630
 
9631
			else{
9632
 
9633
 
9634
 
9635
			compressoffset(&itok);
9636
 
9637
		return;
9638
 
9639
	int razr=typesize(itok.type);
9640
 
9641
		getpointeradr(&itok,bufrm,&strinf,numpointr-1,razr,reg);
9642
 
9643
		else tok=(am32==FALSE?tk_wordvar:tk_dwordvar);
9644
 
9645
	else if(numpointr
9646
 
9647
		tok=(am32==FALSE?tk_wordvar:tk_dwordvar);
9648
 
9649
	else unuseableinput();
9650
 
9651
9652
 
9653
{
9654
 
9655
		wtok->rm=wtok->sib;
9656
 
9657
			wtok->sib=CODE32;
9658
 
9659
		}
9660
 
9661
			wtok->sib=CODE16;
9662
 
9663
		}
9664
 
9665
	}
9666
 
9667
		int razr=typesize(wtok->type);
9668
 
9669
		if(reg==ureg)reg=idxregs[1];
9670
 
9671
			getpointeradr(wtok,wbuf,wstr,npointr-1,razr,reg);
9672
 
9673
			else *otok=(am32==FALSE?tk_wordvar:tk_dwordvar);
9674
 
9675
		else if(npointrnpointr){
9676
 
9677
			if(npointr)getpointeradr(wtok,wbuf,wstr,npointr-1,razr,reg);
9678
 
9679
		}
9680
 
9681
		memcpy(wtok,&itok,sizeof(ITOK));
9682
 
9683
}
9684
 
9685
int CheckAddOnly()
9686
 
9687
ITOK oitok,oitok2;
9688
 
9689
int oinptr,otok,otok2;
9690
 
9691
char *obuf;
9692
 
9693
int retval=TRUE;
9694
 
9695
int changesign=0;
9696
 
9697
	else if(tok!=tk_plusequals)return FALSE;
9698
 
9699
newloop:
9700
 
9701
	bufrm=NULL;
9702
 
9703
	strinf.bufstr=NULL;
9704
 
9705
	oitok2=itok2;
9706
 
9707
	otok2=tok2;
9708
 
9709
	oinptr=inptr2;
9710
 
9711
	while(tok2==tk_minus||tok2==tk_mult)nexttok();
9712
 
9713
		nexttok();
9714
 
9715
			case tk_ID:
9716
 
9717
			case tk_proc:
9718
 
9719
			case tk_undefproc:
9720
 
9721
				retval=FALSE;
9722
 
9723
				break;
9724
 
9725
		if(itok.type==tp_stopper)break;
9726
 
9727
			if(tok!=tk_plus&&tok!=tk_minus){
9728
 
9729
				break;
9730
 
9731
			else if(changesign==2){
9732
 
9733
				char c;
9734
 
9735
					i--;
9736
 
9737
					i--;
9738
 
9739
				i++;
9740
 
9741
				else c='-';
9742
 
9743
			}
9744
 
9745
		}
9746
 
9747
			if(tok!=tk_number&&tok!=tk_postnumber&&tok!=tk_undefofs){
9748
 
9749
				if(bufrm){

					free(bufrm);

					bufrm=NULL;

				}
9750
 
9751
			}
9752
 
9753
		}
9754
 
9755
	itok=oitok;
9756
 
9757
	tok=otok;
9758
 
9759
	linenum2=oline;
9760
 
9761
	cha2=ocha;
9762
 
9763
	bufrm=obuf;
9764
 
9765
	if(j==1)retval=FALSE;
9766
 
9767
		changesign++;
9768
 
9769
	}
9770
 
9771
}
9772
 
9773
int doqwordvar(int terminater)	//64 bit memory variable
9774
 
9775
unsigned char next=1,getfromAX=0;
9776
 
9777
int sign,i;
9778
 
9779
char *wbuf,*rbuf;
9780
 
9781
int retrez=0,pointr=0;
9782
 
9783
int reg;
9784
 
9785
int reg1=idxregs[0],reg2=idxregs[1];
9786
 
9787
	sign=0;
9788
 
9789
	strinf.bufstr=NULL;
9790
 
9791
	wbuf=bufrm;
9792
 
9793
	otok=tok;
9794
 
9795
	switch(tok){
9796
 
9797
			nexttok();
9798
 
9799
			while(tok==tk_mult){
9800
 
9801
				numpointr++;
9802
 
9803
			if(numpointr>itok.npointr){
9804
 
9805
			}
9806
 
9807
			if(itok2.type==tp_opperand){	//сложное выражение
9808
 
9809
					switch(rettype){
9810
 
9811
						case tk_double: sign=3; break;
9812
 
9813
					}
9814
 
9815
						next=0;
9816
 
9817
						goto numbertovar;
9818
 
9819
				}
9820
 
9821
			}
9822
 
9823
				switch(tok){
9824
 
9825
						if((itok.flag&f_reloc)==0){
9826
 
9827
		 						CheckAllMassiv(wbuf,8,&wstr,&wtok);
9828
 
9829
									op66(r32);
9830
 
9831
									op(0x83);
9832
 
9833
									outaddress(&wtok);
9834
 
9835
									if(i==1)break;
9836
 
9837
									compressoffset(&wtok);
9838
 
9839
								break;
9840
 
9841
							if(itok.lnumber==0xFFFFFFFFFFFFFFFFLL){
9842
 
9843
								for(i=0;i<2;i++){
9844
 
9845
									outseg(&wtok,2);
9846
 
9847
									op(wtok.rm+0x8);
9848
 
9849
									op(0xFF);
9850
 
9851
									wtok.number+=4;
9852
 
9853
								}
9854
 
9855
							}
9856
 
9857
numbertovar:
9858
 
9859
						for(i=0;i<2;i++){
9860
 
9861
							if(regoverstack&&short_ok(itok.number,TRUE)&&(itok.flag&f_reloc)==0){
9862
 
9863
								op(itok.number);	//push short number
9864
 
9865
								outseg(&wtok,2);
9866
 
9867
								op(wtok.rm);
9868
 
9869
							}
9870
 
9871
								outseg(&wtok,2);
9872
 
9873
								op(wtok.rm);
9874
 
9875
								if((itok.flag&f_reloc)!=0)AddReloc();
9876
 
9877
							}
9878
 
9879
							itok.lnumber>>=32;
9880
 
9881
							compressoffset(&wtok);
9882
 
9883
						break;
9884
 
9885
					case tk_postnumber:
9886
 
9887
						CheckAllMassiv(wbuf,8,&wstr,&wtok);
9888
 
9889
						outseg(&wtok,2);
9890
 
9891
						op(wtok.rm);
9892
 
9893
						if(tok==tk_apioffset)AddApiToPost(itok.number);
9894
 
9895
							if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
9896
 
9897
//						else if((itok.flag&f_reloc)!=0)AddReloc();
9898
 
9899
						}
9900
 
9901
						compressoffset(&wtok);
9902
 
9903
						outseg(&wtok,2);
9904
 
9905
						op(wtok.rm+0x20);
9906
 
9907
						op(0);
9908
 
9909
					case tk_reg64:
9910
 
9911
					case tk_reg32:
9912
 
9913
							((wtok.rm==rm_d16&&wtok.sib==CODE16)||
9914
 
9915
							op66(r32);
9916
 
9917
							op(0xA3); // MOV [word],AX
9918
 
9919
								AddUndefOff(2,wtok.name);
9920
 
9921
							}
9922
 
9923
							else outdword(wtok.number);
9924
 
9925
						else{
9926
 
9927
							op66(r32);
9928
 
9929
							op(0x89);
9930
 
9931
							outaddress(&wtok);
9932
 
9933
						wtok.number+=4;
9934
 
9935
						op66(r32);
9936
 
9937
						op(0x83);
9938
 
9939
						outaddress(&wtok);
9940
 
9941
						break;
9942
 
9943
						CheckAllMassiv(wbuf,8,&wstr,&wtok);
9944
 
9945
						outseg(&wtok,2);
9946
 
9947
						op(wtok.rm);
9948
 
9949
						outdword(addpoststring());
9950
 
9951
						compressoffset(&wtok);
9952
 
9953
						outseg(&wtok,2);
9954
 
9955
						op(wtok.rm+0x20);
9956
 
9957
						op(0);
9958
 
9959
		 			default:
9960
 
9961
						reg=EAX|(EDX*256);
9962
 
9963
						doregmath64(reg);
9964
 
9965
						next=0;
9966
 
9967
				}
9968
 
9969
			if(getfromAX){
9970
 
9971
				itok.number=EAX|(EDX*256);
9972
 
9973
				reg=itok.number&255;
9974
 
9975
					if(reg==AX&&wbuf==NULL&&wstr.bufstr==NULL&&
9976
 
9977
						(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){
9978
 
9979
						outseg(&wtok,1);
9980
 
9981
						if(wtok.post==UNDEF_OFSET){
9982
 
9983
							wtok.post=0;
9984
 
9985
						if(am32==FALSE)outword(wtok.number);
9986
 
9987
					}
9988
 
9989
						CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2);
9990
 
9991
						outseg(&wtok,2);
9992
 
9993
						op((unsigned int)reg*8+wtok.rm);
9994
 
9995
					}
9996
 
9997
					wtok.number+=4;
9998
 
9999
					reg=itok.number/256;
10000
 
10001
				warningreg(regs[1][EAX]);
10002
 
10003
				ClearReg(AX);
10004
 
10005
				retrez=tk_reg64;
10006
 
10007
			break;
10008
 
10009
		case tk_plusplus:
10010
 
10011
			op66(r32);
10012
 
10013
incdec:
10014
 
10015
			outaddress(&wtok);
10016
 
10017
			compressoffset(&wtok);
10018
 
10019
			op66(r32);
10020
 
10021
			op(0x83); op(0x10+vop+wtok.rm);
10022
 
10023
			op(0);
10024
 
10025
		case tk_xorequals: vop+=0x08;
10026
 
10027
		case tk_andequals: vop+=0x18;
10028
 
10029
		case tk_plusequals:
10030
 
10031
			if(itok2.type==tp_opperand){
10032
 
10033
					if(OnlyNumber(4)){
10034
 
10035
						otok=tok;
10036
 
10037
						goto num;
10038
 
10039
				}
10040
 
10041
			}
10042
 
10043
				switch(tok){
10044
 
10045
					case tk_postnumber:
10046
 
10047
					case tk_apioffset:
10048
 
10049
						for(i=0;i<2;i++){
10050
 
10051
							op66(r32);
10052
 
10053
							if(tok==tk_number&&(itok.flag&f_reloc)==0&&(vop==0||vop==0x28)){
10054
 
10055
									if(vop)vop=8;
10056
 
10057
									goto incdec;
10058
 
10059
								if(itok.number==1){
10060
 
10061
									outaddress(&wtok);
10062
 
10063
								}
10064
 
10065
							if(i==1){
10066
 
10067
								else if(vop==0x28)vop-=0x10;
10068
 
10069
							if(tok!=tk_apioffset&&tok!=tk_undefofs&&tok!=tk_postnumber&&(itok.flag&f_reloc)==0&&
10070
 
10071
								op(0x83);
10072
 
10073
								outaddress(&wtok);
10074
 
10075
							}
10076
 
10077
								op(0x81);
10078
 
10079
								outaddress(&wtok);
10080
 
10081
								else{
10082
 
10083
									else if(tok==tk_undefofs)AddUndefOff(0,itok.name);
10084
 
10085
									outdword(itok.number);
10086
 
10087
							}
10088
 
10089
							wtok.number+=4;
10090
 
10091
							itok.lnumber>>=32;
10092
 
10093
						if(next==0)tok=otok;
10094
 
10095
					case tk_reg64:
10096
 
10097
						for(i=0;i<2;i++){
10098
 
10099
								if(vop==0)vop+=0x10;
10100
 
10101
							}
10102
 
10103
							op66(r32);
10104
 
10105
							op(0x01+vop); op((unsigned int)reg*8+wtok.rm);
10106
 
10107
							if(i==1)break;
10108
 
10109
							compressoffset(&wtok);
10110
 
10111
						}
10112
 
10113
					default:
10114
 
10115
						reg=EAX|(EDX*256);
10116
 
10117
						doregmath64(reg);
10118
 
10119
						reg=EAX;
10120
 
10121
							op66(r32);
10122
 
10123
							op(wtok.rm+reg*8);
10124
 
10125
							if(i==1)break;
10126
 
10127
							if(vop==0x28)vop=0x18;
10128
 
10129
							wtok.number+=4;
10130
 
10131
						}
10132
 
10133
						retrez=tk_reg64;
10134
 
10135
						warningreg(regs[1][EDX]);
10136
 
10137
				}
10138
 
10139
			break;
10140
 
10141
			getoperand(am32==TRUE?EAX:BX);
10142
 
10143
				if(itok.lnumber==1)break;
10144
 
10145
					ZeroReg(EAX,r32);
10146
 
10147
					goto getfromax;
10148
 
10149
				if((i=caselong(itok.number))!=NUMNUM){
10150
 
10151
							((wtok.rm==rm_d16&&wtok.sib==CODE16)||
10152
 
10153
						op66(r32);
10154
 
10155
						op(0xA1); // MOV EAX,[dword]
10156
 
10157
							AddUndefOff(2,wtok.name);
10158
 
10159
						}
10160
 
10161
						else outdword(wtok.number);
10162
 
10163
					else{
10164
 
10165
						op66(r32);
10166
 
10167
						op(0x8B);
10168
 
10169
						outaddress(&wtok);
10170
 
10171
					wtok.number+=4;
10172
 
10173
					ClearReg(AX);
10174
 
10175
					op66(r32);
10176
 
10177
					op(0x0F);
10178
 
10179
					op(wtok.rm);  // SHLD [rmword],CL
10180
 
10181
					op(i);
10182
 
10183
					compressoffset(&wtok);
10184
 
10185
					op66(r32);
10186
 
10187
					op(0xC1);
10188
 
10189
					outaddress(&wtok);
10190
 
10191
					break;
10192
 
10193
			}
10194
 
10195
			wtok.number+=4;
10196
 
10197
			for(i=0;i<2;i++){
10198
 
10199
				outseg(&wtok,2);
10200
 
10201
				outaddress(&wtok);
10202
 
10203
				wtok.number-=4;
10204
 
10205
			}
10206
 
10207
			getintoreg64(reg);
10208
 
10209
			CallExternProc("__llmul");
10210
 
10211
			goto getfromax;
10212
 
10213
			getoperand(am32==TRUE?EAX:BX);
10214
 
10215
				if(itok.number==0){
10216
 
10217
					break;
10218
 
10219
				if(itok.number==1)break;
10220
 
10221
					wtok.number+=4;
10222
 
10223
					if(wbuf==NULL&&wstr.bufstr==NULL&&
10224
 
10225
							(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){
10226
 
10227
						outseg(&wtok,1);
10228
 
10229
						if(wtok.post==UNDEF_OFSET){
10230
 
10231
							wtok.post=0;
10232
 
10233
						if(am32==FALSE)outword(wtok.number);
10234
 
10235
					}
10236
 
10237
						CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2);
10238
 
10239
						outseg(&wtok,2);
10240
 
10241
						op(wtok.rm);
10242
 
10243
					}
10244
 
10245
					compressoffset(&wtok);
10246
 
10247
					CheckAllMassiv(wbuf,8,&wstr,&wtok);
10248
 
10249
					outseg(&wtok,3);
10250
 
10251
					op(0xAC);
10252
 
10253
					outaddress(&wtok);
10254
 
10255
					wtok.number+=4;
10256
 
10257
					CheckAllMassiv(wbuf,8,&wstr,&wtok);
10258
 
10259
					outseg(&wtok,2);
10260
 
10261
					op(0x28+wtok.rm);
10262
 
10263
					op(i);
10264
 
10265
				}
10266
 
10267
				number=itok.lnumber>>32;
10268
 
10269
					op66(r32);
10270
 
10271
						op(0x6A);
10272
 
10273
					}
10274
 
10275
						op(0x68);
10276
 
10277
						outdword(number);
10278
 
10279
					if(i==1)break;
10280
 
10281
				}
10282
 
10283
			}
10284
 
10285
			getintoreg64(reg);
10286
 
10287
			op66(r32);
10288
 
10289
			op66(r32);
10290
 
10291
			next=0;
10292
 
10293
			addESP+=8;
10294
 
10295
			reg=EAX;
10296
 
10297
				if(reg==AX&&wbuf==NULL&&wstr.bufstr==NULL&&
10298
 
10299
					(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){
10300
 
10301
					outseg(&wtok,1);
10302
 
10303
					if(wtok.post==UNDEF_OFSET){
10304
 
10305
					}
10306
 
10307
					else outdword(wtok.number);
10308
 
10309
				else{
10310
 
10311
					op66(r32);
10312
 
10313
					op(0x8B);
10314
 
10315
					outaddress(&wtok);
10316
 
10317
				if(i==1)break;
10318
 
10319
				compressoffset(&wtok);
10320
 
10321
			}
10322
 
10323
			addESP-=8;
10324
 
10325
			compressoffset(&wtok);
10326
 
10327
		case tk_swap:
10328
 
10329
			regdi=TRUE;
10330
 
10331
			rbuf=bufrm;
10332
 
10333
			if(am32!=FALSE&&wbuf!=NULL&&wstr.bufstr!=NULL)regdi=FALSE;
10334
 
10335
				case tk_reg64:
10336
 
10337
					reg=itok.number&255;
10338
 
10339
						op66(r32);
10340
 
10341
						op(0x87);
10342
 
10343
						outaddress(&wtok);
10344
 
10345
						if(i==1)break;
10346
 
10347
						wtok.number+=4;
10348
 
10349
					}
10350
 
10351
				case tk_qwordvar:
10352
 
10353
						getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32,TRUE);
10354
 
10355
						op66(r32);
10356
 
10357
						op(0x87);  // XCHG AX,[wloc]
10358
 
10359
						outaddress(&itok);
10360
 
10361
						if(wbuf==NULL&&wstr.bufstr==NULL&&
10362
 
10363
								(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){
10364
 
10365
							outseg(&wtok,1);
10366
 
10367
							if(wtok.post==UNDEF_OFSET){
10368
 
10369
								wtok.post=0;
10370
 
10371
							if(am32==FALSE)outword(wtok.number);	//????
10372
 
10373
						}
10374
 
10375
							CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2);
10376
 
10377
							outseg(&wtok,2);
10378
 
10379
							outaddress(&wtok);
10380
 
10381
						if(i==1)break;
10382
 
10383
						compressoffset(&itok);
10384
 
10385
						compressoffset(&wtok);
10386
 
10387
					warningreg(regs[1][EAX]);
10388
 
10389
					break;
10390
 
10391
			}
10392
 
10393
		case tk_rrequals:
10394
 
10395
			wtok.number+=4;
10396
 
10397
		case tk_llequals:
10398
 
10399
			if(itok2.type!=tp_stopper){
10400
 
10401
				ClearReg(CX);
10402
 
10403
				next=0;
10404
 
10405
			}
10406
 
10407
				i=0;
10408
 
10409
			else{
10410
 
10411
					getintobeg(CL,&ofsstr);
10412
 
10413
					warningreg(begs[1]);
10414
 
10415
				}
10416
 
10417
			}
10418
 
10419
				((wtok.rm==rm_d16&&wtok.sib==CODE16)||
10420
 
10421
				op66(r32);
10422
 
10423
				op(0xA1); // MOV EAX,[dword]
10424
 
10425
					AddUndefOff(2,wtok.name);
10426
 
10427
				}
10428
 
10429
				else outdword(wtok.number);
10430
 
10431
			else{
10432
 
10433
				op66(r32);
10434
 
10435
				op(0x8B);
10436
 
10437
				outaddress(&wtok);
10438
 
10439
			if(vop)wtok.number-=4;
10440
 
10441
			compressoffset(&wtok);
10442
 
10443
			warningreg(regs[1][EAX]);
10444
 
10445
			op66(r32);
10446
 
10447
			op(0x0F);
10448
 
10449
			op(wtok.rm);  // SHLD [rmword],CL
10450
 
10451
			if(i==0)op((unsigned int)itok.number);
10452
 
10453
			else wtok.number-=4;
10454
 
10455
			CheckAllMassiv(wbuf,8,&wstr,&wtok);
10456
 
10457
			outseg(&wtok,2);
10458
 
10459
			op(0x20+vop+wtok.rm);
10460
 
10461
			if(i==0)op(itok.number);
10462
 
10463
		default: operatorexpected(); break;
10464
 
10465
	KillVar(wtok.name);
10466
 
10467
	if(terminater==tk_semicolon)seminext();
10468
 
10469
	return retrez;
10470
 
10471
10472
 
10473
{
10474
 
10475
	*reg2=idxregs[1];
10476
 
10477
		if(r2==idxregs[1]){
10478
 
10479
			*reg2=idxregs[3];
10480
 
10481
		else{
10482
 
10483
			if(r2==idxregs[2])*reg2=idxregs[3];
10484
 
10485
		}
10486
 
10487
	if(r1==idxregs[1]){
10488
 
10489
			*reg1=idxregs[2];
10490
 
10491
		}
10492
 
10493
			*reg1=idxregs[0];
10494
 
10495
			else *reg2=idxregs[2];
10496
 
10497
	}
10498
 
10499
10500
 
10501
{
10502
 
10503
int vop=0,sign=0;
10504
 
10505
int reg1,reg2;
10506
 
10507
int r1,r2;
10508
 
10509
int rettype;
10510
 
10511
int numpointr=0;
10512
 
10513
	r1=reg&255;
10514
 
10515
	Select2FreeReg(r1,r2,®1,®2);
10516
 
10517
	nexttok();
10518
 
10519
		case tk_assign://=
10520
 
10521
			/*-----------------31.08.05 18:39-------------------
10522
 
10523
			--------------------------------------------------*/
10524
 
10525
			while(tok==tk_mult){
10526
 
10527
				numpointr++;
10528
 
10529
			if(numpointr>itok.npointr){
10530
 
10531
			}
10532
 
10533
			if(tok==tk_number){	//проверка и суммирование чисел
10534
 
10535
					case tk_float: sign=2; break;
10536
 
10537
					case tk_qword: sign=4; break;
10538
 
10539
				if(OnlyNumber(sign)){
10540
 
10541
					MovRegNum(r32,0,itok.lnumber>>32,r2);
10542
 
10543
					break;
10544
 
10545
			}
10546
 
10547
				doeaxfloatmath(tk_stackstart,0,rettype==tk_float?0:4);
10548
 
10549
				op(0x58+r1);
10550
 
10551
				if(rettype==tk_float){
10552
 
10553
				}
10554
 
10555
				next=0;
10556
 
10557
			}
10558
 
10559
10560
 
10561
			getintoreg64(reg);
10562
 
10563
			next=0;
10564
 
10565
		case tk_plusplus: op66(r32); op(0x40+r1);
10566
 
10567
			op(0x83);
10568
 
10569
			op(0);
10570
 
10571
		case tk_minusminus: op66(r32); op(0x48+r1);
10572
 
10573
			op(0x83);
10574
 
10575
			op(0);
10576
 
10577
		case tk_swap:
10578
 
10579
			switch(tok){
10580
 
10581
					reg=r1;
10582
 
10583
						CheckAllMassiv(bufrm,8,&strinf,&itok,reg1,reg2);
10584
 
10585
				 		outseg(&itok,2);
10586
 
10587
						op(reg*8+itok.rm);
10588
 
10589
						itok.number+=4;
10590
 
10591
						reg=r2;
10592
 
10593
					break;
10594
 
10595
					reg=r1;
10596
 
10597
					itok.number&=255;
10598
 
10599
						if(reg!=(int)itok.number){
10600
 
10601
								op66(r32);
10602
 
10603
								else if((unsigned int)itok.number==AX)op(0x90+reg);
10604
 
10605
									op(0x87);
10606
 
10607
								}
10608
 
10609
							else waralreadinitreg(regs[1][reg],regs[1][itok.number]);
10610
 
10611
						reg=r2;
10612
 
10613
					}
10614
 
10615
				default: swaperror(); break;
10616
 
10617
			break;
10618
 
10619
		case tk_minusequals: vop+=0x08;
10620
 
10621
		case tk_orequals: vop+=0x08;
10622
 
10623
			if(CheckAddOnly()){
10624
 
10625
				cha2=' ';
10626
 
10627
				else tok=tk_minus;
10628
 
10629
				next=0;
10630
 
10631
			}
10632
 
10633
			if(itok2.type==tp_opperand&&tok!=tk_number&&tok!=tk_undefofs&&
10634
 
10635
			CheckMinusNum();
10636
 
10637
			int opost;
10638
 
10639
			switch(tok){
10640
 
10641
				case tk_undefofs:
10642
 
10643
					rrec=itok.rec;
10644
 
10645
					char uname[IDLENGTH];
10646
 
10647
					if(itok.flag&f_extern)goto addnum;
10648
 
10649
				case tk_number:
10650
 
10651
					next=0;
10652
 
10653
						sign=reg1|(reg2*256);
10654
 
10655
							op66(r32);
10656
 
10657
							if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii);
10658
 
10659
								if((postnumflag&f_reloc)!=0)AddReloc();
10660
 
10661
							}
10662
 
10663
							ZeroReg(r2,r32);
10664
 
10665
						else{
10666
 
10667
							MovRegNum(r32,postnumflag&f_reloc,ii>>=32,reg2);
10668
 
10669
						doregmath64(sign);
10670
 
10671
						goto addreg;
10672
 
10673
					if((postnumflag&f_reloc)==0&&i!=tk_undefofs&&i!=tk_postnumber){
10674
 
10675
						break;
10676
 
10677
addnum:
10678
 
10679
				  if(r1==AX)op(0x05+vop);
10680
 
10681
						op(0x81);
10682
 
10683
					}
10684
 
10685
					itok.post=opost;
10686
 
10687
					else{
10688
 
10689
						if(i==tk_undefofs)AddUndefOff(2,uname);
10690
 
10691
					outdword(ii);
10692
 
10693
					if(vop==0)vop=0x10;
10694
 
10695
					op66(r32);
10696
 
10697
					else{
10698
 
10699
						op(0xC0+vop+r2);
10700
 
10701
					outdword(ii);
10702
 
10703
				case tk_longvar:
10704
 
10705
					CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2);
10706
 
10707
					outseg(&itok,2);
10708
 
10709
					op(r1*8+itok.rm);
10710
 
10711
					if(vop==0x20){	//&=
10712
 
10713
					}
10714
 
10715
						if(vop==0||vop==0x28){
10716
 
10717
							op66(r32);
10718
 
10719
							op(0xD0+vop+r2);
10720
 
10721
						}
10722
 
10723
					break;
10724
 
10725
					CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2);
10726
 
10727
					for(i=0;i<2;i++){
10728
 
10729
						outseg(&itok,2);
10730
 
10731
						op(reg*8+itok.rm);
10732
 
10733
						if(i==1)break;
10734
 
10735
						itok.number+=4;
10736
 
10737
					}
10738
 
10739
				case tk_reg64:
10740
 
10741
					reg=r1;
10742
 
10743
					for(i=0;i<2;i++){
10744
 
10745
						op(0x01+vop);
10746
 
10747
						if(i==1)break;
10748
 
10749
						if(vop==0x28)vop=0x18;
10750
 
10751
						reg=r2;
10752
 
10753
					break;
10754
 
10755
					op66(r32);
10756
 
10757
					op(0xC0+reg+(unsigned int)itok.number*8);
10758
 
10759
						ZeroReg(r2,r32);
10760
 
10761
					else{
10762
 
10763
							if(vop)vop=8;
10764
 
10765
							op(0x83);
10766
 
10767
							op(0);
10768
 
10769
					}
10770
 
10771
				case tk_ID:
10772
 
10773
				case tk_proc:
10774
 
10775
				case tk_undefproc:
10776
 
10777
unsigned char oaddstack;
10778
 
10779
					if(r1==EAX||r2==EAX){
10780
 
10781
						op(0x50);	//push AX
10782
 
10783
						addESP+=4;
10784
 
10785
						addstack=FALSE;
10786
 
10787
					if(r1==EDX||r2==EDX){
10788
 
10789
						op(0x50+EDX);	//push DX
10790
 
10791
						warningreg(regs[1][EDX]);
10792
 
10793
						addstack=FALSE;
10794
 
10795
					procdo(tk_qword);
10796
 
10797
					if(itok2.type==tp_opperand){
10798
 
10799
						doregmath64(EAX|(EDX*256));
10800
 
10801
					}
10802
 
10803
						op66(r32);
10804
 
10805
						op(0xC0+reg2+EDX*8);	//mov reg,EDX
10806
 
10807
						op(0x58+EDX);	//pop dx
10808
 
10809
					}
10810
 
10811
					if(r1==EAX||r2==EAX){
10812
 
10813
						op(0x89);
10814
 
10815
						op66(r32);
10816
 
10817
						addESP-=4;
10818
 
10819
					else reg1=EAX;
10820
 
10821
					op(0x01+vop);
10822
 
10823
					if(vop==0)vop=0x10;
10824
 
10825
					op66(r32);
10826
 
10827
					op(0xc0+r2+reg2*8);	//add reg,ax
10828
 
10829
				case tk_bytevar:
10830
 
10831
				case tk_beg:
10832
 
10833
				case tk_intvar:
10834
 
10835
 
10836
 
10837
					getintoreg64(sign);
10838
 
10839
					warningreg(regs[1][reg1]);
10840
 
10841
					ClearReg(reg1);
10842
 
10843
					op66(r32);
10844
 
10845
					op(0xc0+r1+reg1*8);	//add reg,ax
10846
 
10847
					if(vop==0x28)vop=0x18;
10848
 
10849
					op(0x01+vop);
10850
 
10851
					next=0;
10852
 
10853
				default: valueexpected(); break;
10854
 
10855
			break;
10856
 
10857
		case tk_llequals:
10858
 
10859
			CheckMinusNum();
10860
 
10861
				ii=doconstqwordmath();
10862
 
10863
				if(itok.type==tp_opperand){
10864
 
10865
					op(0xB0+CL); op(ii);	//mov CL,num
10866
 
10867
					dobegmath(CL);
10868
 
10869
					ClearReg(CL);
10870
 
10871
				}
10872
 
10873
					reg=r1;
10874
 
10875
					r2=reg;
10876
 
10877
				if(ii<32){
10878
 
10879
					op(0x0F);
10880
 
10881
					op(0xC0+r2+r1*8);
10882
 
10883
					op66(r32);
10884
 
10885
						op(0xD1); op(0xE0+r1+vop);
10886
 
10887
					else{
10888
 
10889
						op(0xE0+r1+vop);	//shl ax,num
10890
 
10891
					}
10892
 
10893
				else{
10894
 
10895
					op(0x89);
10896
 
10897
					ii-=32;
10898
 
10899
						op66(r32);
10900
 
10901
							op(0xD1);
10902
 
10903
						}
10904
 
10905
							op(0xC1);
10906
 
10907
							op(ii);
10908
 
10909
					}
10910
 
10911
				}
10912
 
10913
			else if(reg!=CX){
10914
 
10915
					getintobeg(CL,&ofsstr);
10916
 
10917
					warningreg(begs[1]);
10918
 
10919
					next=0;
10920
 
10921
shiftcl:
10922
 
10923
				op(0x0F);
10924
 
10925
				if(vop){
10926
 
10927
					r1=r2;
10928
 
10929
				}
10930
 
10931
				op66(r32);
10932
 
10933
				op(0xE0+vop+r1);	// SHL xXX,CL
10934
 
10935
			else regshifterror();
10936
 
10937
		case tk_multequals:
10938
 
10939
			CheckMinusNum();
10940
 
10941
				ii=doconstqwordmath();
10942
 
10943
				if(itok.type==tp_opperand){
10944
 
10945
					op(0x50+r2);
10946
 
10947
					op(0x50+r1);
10948
 
10949
					MovRegNum(r32,postnumflag&f_reloc,ii,reg1);
10950
 
10951
					ConstToReg(ii,reg1,r32);
10952
 
10953
					doregmath64(reg1|(reg2*256));
10954
 
10955
				}
10956
 
10957
				if((postnumflag&f_reloc)==0){
10958
 
10959
						ZeroReg(r1,r32);
10960
 
10961
						break;
10962
 
10963
					if(ii==1)break;
10964
 
10965
				 		op66(r32);
10966
 
10967
						op(0xC0+9*r1); // ADD r1,r1
10968
 
10969
						op(0x83);
10970
 
10971
						op(0);
10972
 
10973
					}
10974
 
10975
						if(i<32){
10976
 
10977
							outword(0xA40F);
10978
 
10979
							op(i);
10980
 
10981
							op(0xC1);
10982
 
10983
							op(i);
10984
 
10985
						else{
10986
 
10987
							op(0x89);
10988
 
10989
							i-=32;
10990
 
10991
								op66(r32);
10992
 
10993
									op(1);
10994
 
10995
								}
10996
 
10997
									op(0xC1);
10998
 
10999
									op(i);
11000
 
11001
							}
11002
 
11003
						}
11004
 
11005
					}
11006
 
11007
				op66(r32);
11008
 
11009
				op66(r32);
11010
 
11011
				addESP+=8;
11012
 
11013
				MovRegNum(r32,0,ii>>32,EAX);
11014
 
11015
			}
11016
 
11017
			op(0x50+r2);
11018
 
11019
			op(0x50+r1);
11020
 
11021
			reg=ECX|(EAX*256);
11022
 
11023
			getintoreg64(reg);
11024
 
11025
mul:
11026
 
11027
			addESP-=8;
11028
 
11029
			ClearReg(EAX);
11030
 
11031
			ClearReg(EDX);
11032
 
11033
			next=0;
11034
 
11035
				if(r1==EDX){
11036
 
11037
						op66(r32);
11038
 
11039
						break;
11040
 
11041
					op66(r32);
11042
 
11043
					op(0xC0+r2+EDX*8);	//mov reg,EDX
11044
 
11045
					op(0x89);
11046
 
11047
					break;
11048
 
11049
				op66(r32);
11050
 
11051
				op(0xC0+r1+EAX*8);	//mov reg,EAX
11052
 
11053
			if(r2!=EDX){
11054
 
11055
				op(0x89);
11056
 
11057
			}
11058
 
11059
		case tk_divequals:
11060
 
11061
			CheckMinusNum();
11062
 
11063
				ii=doconstqwordmath();
11064
 
11065
				if(itok.type==tp_opperand){
11066
 
11067
					MovRegNum(r32,0,ii>>32,reg2);
11068
 
11069
					ConstToReg(ii>>32,reg2,r32);
11070
 
11071
					op66(r32);
11072
 
11073
					op66(r32);
11074
 
11075
					addESP+=8;
11076
 
11077
					warningreg(regs[1][reg2]);
11078
 
11079
				}
11080
 
11081
					if(ii==0){
11082
 
11083
						break;
11084
 
11085
					if(ii==1)break;
11086
 
11087
						if(i<32){
11088
 
11089
							outword(0xAC0F);
11090
 
11091
							op(i);
11092
 
11093
							op(0xc1);
11094
 
11095
							op(i);
11096
 
11097
						else{
11098
 
11099
							op(0x89);
11100
 
11101
							i-=32;
11102
 
11103
 
11104
 
11105
									op(0xD1);
11106
 
11107
								}
11108
 
11109
									op(0xC1);
11110
 
11111
									op(i);
11112
 
11113
							}
11114
 
11115
						}
11116
 
11117
					}
11118
 
11119
				unsigned long number;
11120
 
11121
				for(i=0;i<2;i++){
11122
 
11123
					if((postnumflag&f_reloc)==0&&short_ok(number,1)){
11124
 
11125
						op(number);
11126
 
11127
					else{
11128
 
11129
						if(i==0&&(postnumflag&f_reloc)!=0)AddReloc();
11130
 
11131
					}
11132
 
11133
					number=ii;
11134
 
11135
				addESP+=8;
11136
 
11137
			}
11138
 
11139
			getintoreg64(reg);
11140
 
11141
			op66(r32);
11142
 
11143
			op66(r32);
11144
 
11145
			addESP+=8;
11146
 
11147
			warningreg(regs[1][reg2]);
11148
 
11149
divcont:
11150
 
11151
				if(r2==EAX){
11152
 
11153
						op66(r32);
11154
 
11155
						goto sdiv;
11156
 
11157
					op66(r32);
11158
 
11159
					op(0xC0+EDX+r2*8);	//mov EDX,r2
11160
 
11161
					op(0x89);
11162
 
11163
					goto sdiv;
11164
 
11165
				op66(r32);
11166
 
11167
				op(0xC0+EAX+r1*8);	//mov EAX,r1
11168
 
11169
			if(r2!=EDX){
11170
 
11171
				op(0x89);
11172
 
11173
			}
11174
 
11175
			CallExternProc("__lludiv");
11176
 
11177
			goto endmul;
11178
 
11179
	}
11180
 
11181
	ClearReg(r2);
11182
 
11183
	if(terminater==tk_semicolon)seminext();
11184
 
11185
}
11186
 
11187
void optnumadd64(unsigned long long num,int r1,int r2,int vop)
11188
 
11189
int i,reg;
11190
 
11191
		if(vop==0x20){	//&=
11192
 
11193
			for(i=0;i<2;i++){
11194
 
11195
				reg=r2;
11196
 
11197
			setzeroflag=TRUE;
11198
 
11199
		return;		//+= -= |= ^=
11200
 
11201
	if(num==1){
11202
 
11203
			op66(r32);
11204
 
11205
			op66(r32);
11206
 
11207
			op(0xD8+r2);
11208
 
11209
			setzeroflag=TRUE;
11210
 
11211
		}
11212
 
11213
			op66(r32);
11214
 
11215
			op66(r32);
11216
 
11217
			op(0xD0+r2);
11218
 
11219
			setzeroflag=TRUE;
11220
 
11221
		}
11222
 
11223
	if(vop==8){	//|=
11224
 
11225
			if((unsigned short)num<256&&r1<4){
11226
 
11227
				else{
11228
 
11229
					op(0xc8+r1);
11230
 
11231
				op(num);
11232
 
11233
			}
11234
 
11235
			if(r1==AX)op(0x0D);
11236
 
11237
				op(0x81);
11238
 
11239
			}
11240
 
11241
			return;
11242
 
11243
		if(num<0x100000000LL){
11244
 
11245
			if(r1==AX)op(0x0D);
11246
 
11247
				op(0x81);
11248
 
11249
			}
11250
 
11251
			return;
11252
 
11253
	}
11254
 
11255
		if(num>=0xFFFFFFFF00000000LL){
11256
 
11257
				if((unsigned short)num>=0xFF00&&r1<4){
11258
 
11259
					else{
11260
 
11261
						op(0xE0+r1);
11262
 
11263
					op(num);
11264
 
11265
				}
11266
 
11267
				if(r1==AX)op(0x25);
11268
 
11269
					op(129);
11270
 
11271
				}
11272
 
11273
				return;
11274
 
11275
			op66(r32);
11276
 
11277
			else{
11278
 
11279
				op(0xE0+r1);
11280
 
11281
			outdword(num);
11282
 
11283
		}
11284
 
11285
	reg=r1;
11286
 
11287
	for(i=0;i<2;i++){
11288
 
11289
		if(optnumadd(num,reg,r32,vop)==FALSE){
11290
 
11291
			if(short_ok((unsigned long)num,TRUE)){
11292
 
11293
				op(0xC0+vop+reg);
11294
 
11295
			}
11296
 
11297
				if(reg==EAX)op(5+vop);
11298
 
11299
				  op(0x81);
11300
 
11301
				}
11302
 
11303
			}
11304
 
11305
		num>>=32;
11306
 
11307
			if(vop)vop=8;
11308
 
11309
			if(short_ok((unsigned long)num,TRUE)){
11310
 
11311
				op(0xD0+vop+r2);
11312
 
11313
			}
11314
 
11315
				if(r2==EAX)op(0x15+vop);
11316
 
11317
				  op(0x81);
11318
 
11319
				}
11320
 
11321
			}
11322
 
11323
		}
11324
 
11325
	}
11326
 
11327
}
11328
 
11329
void doregmath64(int reg)
11330
 
11331
int vop,i,optnum,negflag=FALSE;
11332
 
11333
int reg1,reg2;
11334
 
11335
	r1=reg&255;
11336
 
11337
	Select2FreeReg(r1,r2,®1,®2);
11338
 
11339
		if(negflag){
11340
 
11341
			op(0xF7);
11342
 
11343
			op66(r32);
11344
 
11345
			op(0xD8+r1);  // NEG reg
11346
 
11347
			op(0x83);
11348
 
11349
			op(0);
11350
 
11351
			ClearReg(r2);
11352
 
11353
		}
11354
 
11355
		next=1;
11356
 
11357
		if(tok2==tk_number)optnum=OptimNum();
11358
 
11359
			case tk_xor: vop+=0x08;
11360
 
11361
			case tk_and: vop+=0x18;
11362
 
11363
			case tk_plus:
11364
 
11365
				else tok=tk_number;
11366
 
11367
					case tk_number:
11368
 
11369
							optnumadd64(itok.lnumber,r1,r2,vop);
11370
 
11371
						}
11372
 
11373
					case tk_undefofs:
11374
 
11375
						op66(r32);
11376
 
11377
						op(0xC0+vop+r1);
11378
 
11379
						else{
11380
 
11381
							else if(tok==tk_undefofs)AddUndefOff(0,itok.name);
11382
 
11383
							outdword(itok.number);
11384
 
11385
						if(vop==0x20){	//&=
11386
 
11387
						}
11388
 
11389
							if(vop==0||vop==0x28){
11390
 
11391
								op66(r32);
11392
 
11393
								op(0xD0+vop+r2);
11394
 
11395
							}
11396
 
11397
						break;
11398
 
11399
					case tk_charvar:
11400
 
11401
					case tk_bytevar:
11402
 
11403
						op66(r32);
11404
 
11405
						op(0xC0+r1+reg2*8);	/* OPT AX,CX */
11406
 
11407
							ZeroReg(r2,r32);
11408
 
11409
						else{
11410
 
11411
								if(vop)vop=8;
11412
 
11413
								op(0x83);
11414
 
11415
								op(0);
11416
 
11417
						}
11418
 
11419
						next=0;
11420
 
11421
		  		case tk_reg:
11422
 
11423
						outword(0xB70F);
11424
 
11425
						op(0xC0+itok.number*9);
11426
 
11427
					case tk_reg32:
11428
 
11429
						op66(r32);
11430
 
11431
						op(0xC0+r1+(unsigned int)itok.number*8);
11432
 
11433
							ZeroReg(r2,r32);
11434
 
11435
						else{
11436
 
11437
								if(vop)vop=8;
11438
 
11439
								op(0x83);
11440
 
11441
								op(0);
11442
 
11443
						}
11444
 
11445
					case tk_reg64:
11446
 
11447
						reg=r1;
11448
 
11449
						for(i=0;i<2;i++){
11450
 
11451
							op(0x01+vop);
11452
 
11453
							if(i==1)break;
11454
 
11455
							if(vop==0x28)vop=0x18;
11456
 
11457
							reg=r2;
11458
 
11459
						break;
11460
 
11461
					case tk_dwordvar:
11462
 
11463
						op66(r32);
11464
 
11465
						op(0x03+vop);
11466
 
11467
						outaddress(&itok);
11468
 
11469
							ZeroReg(r2,r32);
11470
 
11471
						else{
11472
 
11473
								if(vop)vop=8;
11474
 
11475
								op(0x83);
11476
 
11477
								op(0);
11478
 
11479
						}
11480
 
11481
					case tk_qwordvar:
11482
 
11483
						for(i=0;i<2;i++){
11484
 
11485
							op66(r32);
11486
 
11487
							op(0x03+vop);
11488
 
11489
							outaddress(&itok);
11490
 
11491
							if(vop==0)vop=0x10;
11492
 
11493
							itok.number+=4;
11494
 
11495
							reg=r2;
11496
 
11497
						break;
11498
 
11499
					case tk_id:
11500
 
11501
					case tk_apiproc:
11502
 
11503
					case tk_declare:
11504
 
11505
						op66(r32);
11506
 
11507
						op(0xc0+r1);
11508
 
11509
						if(vop==0)vop=0x10;
11510
 
11511
						op66(r32);
11512
 
11513
						op(0xc0+r2+EDX*8);
11514
 
11515
						break;
11516
 
11517
				}
11518
 
11519
			case tk_rrminus:
11520
 
11521
					regshifterror();
11522
 
11523
				}
11524
 
11525
				goto rshift2;
11526
 
11527
			  getoperand(ECX);
11528
 
11529
					op66(r32);
11530
 
11531
					op(0xC0+r1+r2*8);
11532
 
11533
					op66(r32);
11534
 
11535
						op(0xD1); op(0xE8+r2);  // SHR reg,1
11536
 
11537
					else if((unsigned int)itok.number!=0){
11538
 
11539
						op(0xe8+r2); // SHR reg,imm8
11540
 
11541
					}
11542
 
11543
				else if(r1==ECX||r2==ECX)regshifterror();
11544
 
11545
				else{
11546
 
11547
					getintobeg(CL,&ofsstr);
11548
 
11549
					warningreg(begs[1]);
11550
 
11551
					op66(r32);
11552
 
11553
					op(0xC0+r1+r2*8);
11554
 
11555
					op(0xD3);
11556
 
11557
				}
11558
 
11559
			case tk_llminus:
11560
 
11561
					regshifterror();
11562
 
11563
				}
11564
 
11565
				goto llshift;
11566
 
11567
			  getoperand(ECX);
11568
 
11569
					op66(r32);
11570
 
11571
					op(0xC0+r2+r1*8);
11572
 
11573
					op66(r32);
11574
 
11575
						op(1);
11576
 
11577
					}
11578
 
11579
						op(0xC1);
11580
 
11581
						op(itok.number);
11582
 
11583
				}
11584
 
11585
				else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==CL)goto lshift;
11586
 
11587
llshift:
11588
 
11589
					next=0;
11590
 
11591
lshift:
11592
 
11593
					outword(0xA50F);
11594
 
11595
					op66(r32);
11596
 
11597
					op(0xE0+r1);	// SHL xXX,CL
11598
 
11599
				break;
11600
 
11601
			case tk_mult:
11602
 
11603
				if(negflag&&tok==tk_number){
11604
 
11605
					negflag=FALSE;
11606
 
11607
				if(tok==tk_number&&((itok.number&f_reloc)==0)){
11608
 
11609
						ZeroReg(r1,r32);
11610
 
11611
						break;
11612
 
11613
					if(itok.lnumber==1)break;
11614
 
11615
				 		op66(r32);
11616
 
11617
						op(0xC0+9*r1); // ADD r1,r1
11618
 
11619
						op(0x83);
11620
 
11621
						op(0);
11622
 
11623
					}
11624
 
11625
						if(i<32){
11626
 
11627
							outword(0xA40F);
11628
 
11629
							op(i);
11630
 
11631
							op(0xC1);
11632
 
11633
 
11634
 
11635
						else{
11636
 
11637
							op(0x89);
11638
 
11639
							i-=32;
11640
 
11641
								op66(r32);
11642
 
11643
									op(1);
11644
 
11645
								}
11646
 
11647
									op(0xC1);
11648
 
11649
									op(i);
11650
 
11651
							}
11652
 
11653
						}
11654
 
11655
					}
11656
 
11657
					op(0x50+r2);
11658
 
11659
					op(0x50+r1);
11660
 
11661
					MovRegNum(r32,postnumflag&f_reloc,itok.number,ECX);
11662
 
11663
					goto mul;
11664
 
11665
				//вызов процедуры __llmul
11666
 
11667
				op(0x50+r2);
11668
 
11669
				op(0x50+r1);
11670
 
11671
				reg=ECX|(EAX*256);
11672
 
11673
//				doregmath64(reg);
11674
 
11675
mul:
11676
 
11677
				addESP-=8;
11678
 
11679
				if(r1!=EAX){
11680
 
11681
						if(r2==EAX){
11682
 
11683
							op(0x90+EDX);
11684
 
11685
						}
11686
 
11687
						op(0x89);
11688
 
11689
						op66(r32);
11690
 
11691
						op(0xC0+r1+EAX*8);	//mov reg,EAX
11692
 
11693
					}
11694
 
11695
					op(0x89);
11696
 
11697
				}
11698
 
11699
					op66(r32);
11700
 
11701
					op(0xC0+r2+EDX*8);	//mov reg,EDX
11702
 
11703
				break;
11704
 
11705
			case tk_mod:
11706
 
11707
				goto divcalc;;
11708
 
11709
			case tk_div:
11710
 
11711
			  getoperand(reg1);
11712
 
11713
					itok.lnumber=-itok.lnumber;
11714
 
11715
				}
11716
 
11717
					if(itok.lnumber==0){
11718
 
11719
						break;
11720
 
11721
					if(itok.lnumber==1){
11722
 
11723
							ZeroReg(r1,r32);
11724
 
11725
						}
11726
 
11727
					}
11728
 
11729
						if(vop){	//mod
11730
 
11731
						}
11732
 
11733
							if(i<32){
11734
 
11735
								outword(0xAC0F);
11736
 
11737
								op(i);
11738
 
11739
								op(0xc1);
11740
 
11741
								op(i);
11742
 
11743
							else{
11744
 
11745
								op(0x89);
11746
 
11747
								i-=32;
11748
 
11749
									op66(r32);
11750
 
11751
										op(0xD1);
11752
 
11753
									}
11754
 
11755
										op(0xC1);
11756
 
11757
										op(i);
11758
 
11759
								}
11760
 
11761
							}
11762
 
11763
						break;
11764
 
11765
					unsigned long number;
11766
 
11767
					for(i=0;i<2;i++){
11768
 
11769
						if((itok.flag&f_reloc)==0&&short_ok(number,1)){
11770
 
11771
							op(number);
11772
 
11773
						else{
11774
 
11775
							if(i==0&&(itok.flag&f_reloc)!=0)AddReloc();
11776
 
11777
						}
11778
 
11779
						number=itok.number;
11780
 
11781
					addESP+=8;
11782
 
11783
				}
11784
 
11785
				getintoreg64(reg);
11786
 
11787
				op(0x50+reg2);
11788
 
11789
				op(0x50+reg1);
11790
 
11791
				next=0;
11792
 
11793
		 		if(r1!=EAX){
11794
 
11795
						if(r1==EDX){
11796
 
11797
							op(0x90+EDX);
11798
 
11799
						}
11800
 
11801
						op(0x89);
11802
 
11803
						op66(r32);
11804
 
11805
						op(0xC0+EAX+r1*8);	//mov EAX,r1
11806
 
11807
					}
11808
 
11809
					op(0x89);
11810
 
11811
				}
11812
 
11813
					op66(r32);
11814
 
11815
					op(0xC0+EDX+r2*8);	//mov EDX,r2
11816
 
11817
sdiv:
11818
 
11819
				addESP-=8;
11820
 
11821
			default: operatorexpected(); break;
11822
 
11823
		if(next)nexttok();
11824
 
11825
	ClearReg(r1);
11826
 
11827
	if(cpu<3)cpu=3;
11828
 
11829
11830
 
11831
{
11832
 
11833
unsigned long long holdnumber=0;
11834
 
11835
int reg1,reg2;
11836
 
11837
	r2=reg/256;
11838
 
11839
	if(tok==tk_minus){
11840
 
11841
			negflag=1;
11842
 
11843
		}
11844
 
11845
	switch(tok){
11846
 
11847
			holdnumber=CalcNumber(4);
11848
 
11849
			MovRegNum(r32,0,holdnumber>>32,r2);
11850
 
11851
			break;
11852
 
11853
		case tk_undefofs:
11854
 
11855
			op66(r32);
11856
 
11857
			if(tok==tk_apioffset)AddApiToPost(itok.number);
11858
 
11859
				if(tok==tk_undefofs)AddUndefOff(0,itok.name);
11860
 
11861
				tok=tk_number;
11862
 
11863
				outdword(holdnumber);
11864
 
11865
 
11866
 
11867
			ClearReg(r1);
11868
 
11869
			break;
11870
 
11871
			CheckAllMassiv(bufrm,8,&strinf,&itok,reg1,reg2);
11872
 
11873
				op66(r32);
11874
 
11875
				if(itok.post==0)outseg(&itok,2);
11876
 
11877
				op(r1*8+itok.rm);
11878
 
11879
					if((itok.flag&f_extern)==0){
11880
 
11881
						if(am32&&itok.rm==rm_sib)outptr++;
11882
 
11883
						outptr=ooutptr;
11884
 
11885
					else setwordext(&itok.number);
11886
 
11887
				outaddress(&itok);
11888
 
11889
 
11890
 
11891
			break;
11892
 
11893
			reg=r1;
11894
 
11895
				if(reg==EAX&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){
11896
 
11897
					outseg(&itok,1);
11898
 
11899
					if(itok.post==UNDEF_OFSET)AddUndefOff(2,itok.name);
11900
 
11901
					else outdword(itok.number);
11902
 
11903
				else{
11904
 
11905
			 		op66(r32);
11906
 
11907
					op(0x8B);
11908
 
11909
					outaddress(&itok);
11910
 
11911
 
11912
 
11913
				itok.number+=4;
11914
 
11915
 
11916
 
11917
			break;
11918
 
11919
		case tk_dwordvar:
11920
 
11921
		 		op66(r32);
11922
 
11923
				op(0xA1);
11924
 
11925
				if(am32==FALSE)outword((unsigned int)itok.number);
11926
 
11927
			}
11928
 
11929
				CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2);
11930
 
11931
				outseg(&itok,2);
11932
 
11933
				op(r1*8+itok.rm);
11934
 
11935
			}
11936
 
11937
			ClearReg(r1);
11938
 
11939
		case tk_intvar:
11940
 
11941
			CheckAllMassiv(bufrm,2,&strinf,&itok,reg1,reg2);
11942
 
11943
				ZeroReg(r1,r32);
11944
 
11945
				outseg(&itok,2);	//mov reg,var
11946
 
11947
			}
11948
 
11949
		 		op66(r32);
11950
 
11951
				op(0x0F); op(tok==tk_wordvar?0xB7:0xBF);
11952
 
11953
			op(r1*8+itok.rm);
11954
 
11955
			ClearReg(r1);
11956
 
11957
			break;
11958
 
11959
		case tk_charvar:
11960
 
11961
			if(reg<=EBX&&tok==tk_bytevar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){
11962
 
11963
				outseg(&itok,2);
11964
 
11965
			}
11966
 
11967
				op66(r32);
11968
 
11969
				op(0xf);
11970
 
11971
				else op(0xbe);
11972
 
11973
			op(r1*8+itok.rm); // MOVZX regL,[byte]
11974
 
11975
			ClearReg(r1);
11976
 
11977
			break;
11978
 
11979
			if(tok2==tk_openbracket){	//вызов процедуры по адресу в регистре
11980
 
11981
				nexttok();
11982
 
11983
				if(comfile==file_w32)swapparam();
11984
 
11985
				op66(r16);
11986
 
11987
				op(0xD0+reg1); 	/* CALL reg with stack params */
11988
 
11989
				clearregstat();
11990
 
11991
				FreeGlobalConst();
11992
 
11993
			}
11994
 
11995
				ZeroReg(r1,r32);
11996
 
11997
				op(0xC0+r1+(unsigned int)itok.number*8);
11998
 
11999
			else{
12000
 
12001
				outword(0xB70F);
12002
 
12003
			}
12004
 
12005
			ZeroReg(r2,r32);
12006
 
12007
		case tk_reg32:
12008
 
12009
				reg1=itok.number;
12010
 
12011
				param[0]=0;
12012
 
12013
				else doparams();
12014
 
12015
				op(0xFF);
12016
 
12017
				itok.number=0;
12018
 
12019
#ifdef OPTVARCONST
12020
 
12021
#endif
12022
 
12023
			if(r1!=(int)itok.number){
12024
 
12025
				op(0x89);
12026
 
12027
				RegToReg(r1,itok.number,r32);
12028
 
12029
			ZeroReg(r2,r32);
12030
 
12031
		case tk_reg64:
12032
 
12033
			reg2=itok.number/256;
12034
 
12035
			if(r1==reg2){
12036
 
12037
					op66(r32);
12038
 
12039
					else if(r2==AX)op(0x90+r1);
12040
 
12041
						op(0x87);
12042
 
12043
					}
12044
 
12045
				}
12046
 
12047
				temp=r2;
12048
 
12049
				r1=temp;
12050
 
12051
				reg2=reg1;
12052
 
12053
			}
12054
 
12055
				int temp;
12056
 
12057
				r2=r1;
12058
 
12059
				temp=reg2;
12060
 
12061
				reg1=temp;
12062
 
12063
			if(r1!=reg1){
12064
 
12065
				op(0x89);
12066
 
12067
				RegToReg(r1,reg1,r32);
12068
 
12069
			if(r2!=reg2){
12070
 
12071
				op(0x89);
12072
 
12073
				RegToReg(r2,reg2,r32);
12074
 
12075
			break;
12076
 
12077
			int vops;
12078
 
12079
			if(i<=64)vops=r64;
12080
 
12081
			if(i<=16)vops=r16;
12082
 
12083
			ZeroReg(r2,r32);
12084
 
12085
		case tk_seg:
12086
 
12087
			op(0x8C);
12088
 
12089
			ClearReg(r1);
12090
 
12091
			break;
12092
 
12093
			if(optimizespeed&&chip>3&&chip<7&®<4&®!=(int)(itok.number%4)){
12094
 
12095
				op(0x88);
12096
 
12097
			}
12098
 
12099
				op66(r32);
12100
 
12101
				op(0xC0+r1*8+(unsigned int)itok.number); // MOVZX regL,beg
12102
 
12103
			ClearReg(reg);
12104
 
12105
			break;
12106
 
12107
			getoperand(am32==FALSE?BX:reg);
12108
 
12109
		case tk_ID:
12110
 
12111
		case tk_proc:
12112
 
12113
		case tk_undefproc:
12114
 
12115
			if((!i)||macros(tk_qword)==0)procdo(tk_qword);
12116
 
12117
			goto movreg64;
12118
 
12119
			op66(r32);
12120
 
12121
			outdword(addpoststring());
12122
 
12123
			ZeroReg(r2,r32);
12124
 
12125
		default: valueexpected();	break;
12126
 
12127
	if(negflag){
12128
 
12129
		op(0xF7);
12130
 
12131
		op66(r32);
12132
 
12133
		op(0xD8+r1);  // NEG reg
12134
 
12135
		op(0x83);
12136
 
12137
		op(0);
12138
 
12139
		ClearReg(r2);
12140
 
12141
	if(next)nexttok();
12142
 
12143
12144
 
12145
{
12146
 
12147
int tok4=tk_id;
12148
 
12149
struct idrec *ptrs;
12150
 
12151
	strcpy(string4,name);
12152
 
12153
	ptrs=itok4.rec;
12154
 
12155
		case tk_id:
12156
 
12157
			itok4=itok;
12158
 
12159
			string[0]=0;
12160
 
12161
			tok=tk_undefproc;
12162
 
12163
			itok.segm=NOT_DYNAMIC;
12164
 
12165
			itok.post=0;
12166
 
12167
			addacall(secondcallnum++,CALL_NEAR);
12168
 
12169
			itok=itok4;
12170
 
12171
			break;
12172
 
12173
			ptrs->rectok=tk_undefproc;
12174
 
12175
			addacall(itok4.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR));
12176
 
12177
			break;
12178
 
12179
			if(itok4.segm==DYNAMIC)itok4.segm=ptrs->recsegm=DYNAMIC_USED;
12180
 
12181
				addacall(itok4.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR));
12182
 
12183
			}
12184
 
12185
				callloc(itok4.number);
12186
 
12187
			break;
12188
 
12189
			sprintf(string4,"'%s' already used",name);
12190
 
12191
			break;
12192
 
12193
}
12194
 
12195
>
12196
 
12197
>
12198
 
12199
>
12200
 
12201
>
12202
 
12203
>
12204
 
12205
}
12206
 
12207
void>
12208
 
12209
>
12210
 
12211
>
12212
 
12213
>
12214
 
12215
>
12216
 
12217
>
12218
 
12219
>
12220
 
12221
12222
 
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
void>
12272
 
12273
>
12274
 
12275
>
12276
 
12277
>
12278
 
12279
>
12280
 
12281
12282
 
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
 
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
 
12363
>
12364
 
12365
>
12366
 
12367
>
12368
 
12369
>
12370
 
12371
>
12372
 
12373
}
12374
 
12375
int>
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
 
12401
>
12402
 
12403
>
12404
 
12405
>
12406
 
12407
>
12408
 
12409
>
12410
 
12411
>
12412
 
12413
>
12414
 
12415
>
12416
 
12417
>
12418
 
12419
>
12420
 
12421