* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / as / mops.c
blobd18510dd7661d736d77138af9ed44522a889b55b
1 /* mops.c - handle pseudo-ops */
3 #include "syshead.h"
4 #include "const.h"
5 #include "type.h"
6 #include "globvar.h"
7 #include "opcode.h"
8 #include "scan.h"
9 #undef EXTERN
10 #define EXTERN
11 #include "address.h"
13 #define is8bitadr(offset) ((offset_t) offset < 0x100)
14 #define is8bitsignedoffset(offset) ((offset_t) (offset) + 0x80 < 0x100)
15 #define pass2 (pass==last_pass)
17 FORWARD void mshort2 P((void));
18 FORWARD reg_pt regchk P((void));
19 FORWARD void reldata P((void));
20 FORWARD void segadj P((void));
22 #ifdef I80386
24 #define iswordadr(offset) ((offset_t) (offset) < 0x10000L)
25 #define iswordoffset(offset) ((offset_t) (offset) + 0x8000L < 0x10000L)
26 #define iswordorswordoffset(offset) ((offset_t) (offset) + 0xFFFFL < 0x1FFFEL)
28 #define BYTE_SEGWORD 0x00
29 #define isspecreg(r) ((r) >= CR0REG && (r) <= TR7REG)
31 #define BASE_MASK 0x07
32 #define BASE_SHIFT 0
33 #define INDEX_MASK 0x38
34 #define INDEX_SHIFT 3
35 #define MOD_MASK 0xC0
36 # define REG_MOD 0xC0
37 # define MEM0_MOD 0x00
38 # define MEM1_MOD 0x40
39 # define MEM2_MOD 0x80
40 #define REG_MASK 0x38
41 #define REG_SHIFT 3
42 #define RM_MASK 0x07
43 #define RM_SHIFT 0
44 # define D16_RM 0x06
45 # define D32_RM 0x05
46 # define SIB_NOBASE 0x05
47 # define SIB_RM 0x04
48 #define SREG_MASK 0x38
49 #define SREG_SHIFT 3
50 #define SS_MASK 0xC0
51 #define SS_SHIFT 6
53 #define SEGMOV 0x04
54 #define SIGNBIT 0x02
55 #define TOREGBIT 0x02
56 #define WORDBIT 0x01
58 PRIVATE opcode_t baseind16[] =
60 0x00, /* BP + BP, illegal */
61 0x00, /* BX + BP, illegal */
62 0x03, /* DI + BP */
63 0x02, /* SI + BP */
64 0x00, /* BP + BX, illegal */
65 0x00, /* BX + BX, illegal */
66 0x01, /* DI + BX */
67 0x00, /* SI + BX */
68 0x03, /* BP + DI */
69 0x01, /* BX + DI */
70 0x00, /* DI + DI, illegal */
71 0x00, /* SI + DI, illegal */
72 0x02, /* BP + SI */
73 0x00, /* BX + SI */
74 0x00, /* DI + SI, illegal */
75 0x00, /* SI + SI, illegal */
78 PRIVATE opcode_t regbits[] =
80 0x05 << REG_SHIFT, /* BP */
81 0x03 << REG_SHIFT, /* BX */
82 0x07 << REG_SHIFT, /* DI */
83 0x06 << REG_SHIFT, /* SI */
85 0x00 << REG_SHIFT, /* EAX */
86 0x05 << REG_SHIFT, /* EBP */
87 0x03 << REG_SHIFT, /* EBX */
88 0x01 << REG_SHIFT, /* ECX */
89 0x07 << REG_SHIFT, /* EDI */
90 0x02 << REG_SHIFT, /* EDX */
91 0x06 << REG_SHIFT, /* ESI */
92 0x04 << REG_SHIFT, /* ESP */
94 0x00 << REG_SHIFT, /* AX */
95 0x01 << REG_SHIFT, /* CX */
96 0x02 << REG_SHIFT, /* DX */
97 0x04 << REG_SHIFT, /* SP */
99 0x04 << REG_SHIFT, /* AH */
100 0x00 << REG_SHIFT, /* AL */
101 0x07 << REG_SHIFT, /* BH */
102 0x03 << REG_SHIFT, /* BL */
103 0x05 << REG_SHIFT, /* CH */
104 0x01 << REG_SHIFT, /* CL */
105 0x06 << REG_SHIFT, /* DH */
106 0x02 << REG_SHIFT, /* DL */
108 0x01 << REG_SHIFT, /* CS */
109 0x03 << REG_SHIFT, /* DS */
110 0x00 << REG_SHIFT, /* ES */
111 0x04 << REG_SHIFT, /* FS */
112 0x05 << REG_SHIFT, /* GS */
113 0x02 << REG_SHIFT, /* SS */
115 0x00 << REG_SHIFT, /* CR0 */
116 0x02 << REG_SHIFT, /* CR2 */
117 0x03 << REG_SHIFT, /* CR3 */
119 0x00 << REG_SHIFT, /* DR0 */
120 0x01 << REG_SHIFT, /* DR1 */
121 0x02 << REG_SHIFT, /* DR2 */
122 0x03 << REG_SHIFT, /* DR3 */
123 0x06 << REG_SHIFT, /* DR6 */
124 0x07 << REG_SHIFT, /* DR7 */
126 0x03 << REG_SHIFT, /* TR3 */
127 0x04 << REG_SHIFT, /* TR4 */
128 0x05 << REG_SHIFT, /* TR5 */
129 0x06 << REG_SHIFT, /* TR6 */
130 0x07 << REG_SHIFT, /* TR7 */
132 0x00 << REG_SHIFT, /* ST(0) */
133 0x01 << REG_SHIFT, /* ST(1) */
134 0x02 << REG_SHIFT, /* ST(2) */
135 0x03 << REG_SHIFT, /* ST(3) */
136 0x04 << REG_SHIFT, /* ST(4) */
137 0x05 << REG_SHIFT, /* ST(5) */
138 0x06 << REG_SHIFT, /* ST(6) */
139 0x07 << REG_SHIFT, /* ST(7) */
142 PRIVATE opsize_t regsize[] =
144 2, /* BP */
145 2, /* BX */
146 2, /* DI */
147 2, /* SI */
149 4, /* EAX */
150 4, /* EBP */
151 4, /* EBX */
152 4, /* ECX */
153 4, /* EDI */
154 4, /* EDX */
155 4, /* ESI */
156 4, /* ESP */
158 2, /* AX */
159 2, /* CX */
160 2, /* DX */
161 2, /* SP */
163 1, /* AH */
164 1, /* AL */
165 1, /* BH */
166 1, /* BL */
167 1, /* CH */
168 1, /* CL */
169 1, /* DH */
170 1, /* DL */
172 2, /* CS */
173 2, /* DS */
174 2, /* ES */
175 2, /* FS */
176 2, /* GS */
177 2, /* SS */
179 4, /* CR0 */
180 4, /* CR2 */
181 4, /* CR3 */
183 4, /* DR0 */
184 4, /* DR1 */
185 4, /* DR2 */
186 4, /* DR3 */
187 4, /* DR6 */
188 4, /* DR7 */
190 4, /* TR3 */
191 4, /* TR4 */
192 4, /* TR5 */
193 4, /* TR6 */
194 4, /* TR7 */
196 10, /* ST(0) */
197 10, /* ST(1) */
198 10, /* ST(2) */
199 10, /* ST(3) */
200 10, /* ST(4) */
201 10, /* ST(5) */
202 10, /* ST(6) */
203 10, /* ST(7) */
205 0, /* NOREG */
208 PRIVATE opcode_t regsegword[] =
210 WORDBIT, /* BP */
211 WORDBIT, /* BX */
212 WORDBIT, /* DI */
213 WORDBIT, /* SI */
215 WORDBIT, /* EAX */
216 WORDBIT, /* EBP */
217 WORDBIT, /* EBX */
218 WORDBIT, /* ECX */
219 WORDBIT, /* EDI */
220 WORDBIT, /* EDX */
221 WORDBIT, /* ESI */
222 WORDBIT, /* ESP */
224 WORDBIT, /* AX */
225 WORDBIT, /* CX */
226 WORDBIT, /* DX */
227 WORDBIT, /* SP */
229 BYTE_SEGWORD, /* AH */
230 BYTE_SEGWORD, /* AL */
231 BYTE_SEGWORD, /* BH */
232 BYTE_SEGWORD, /* BL */
233 BYTE_SEGWORD, /* CH */
234 BYTE_SEGWORD, /* CL */
235 BYTE_SEGWORD, /* DH */
236 BYTE_SEGWORD, /* DL */
238 SEGMOV, /* CS */
239 SEGMOV, /* DS */
240 SEGMOV, /* ES */
241 SEGMOV, /* FS */
242 SEGMOV, /* GS */
243 SEGMOV, /* SS */
245 0x20, /* CR0 */
246 0x20, /* CR2 */
247 0x20, /* CR3 */
249 0x21, /* DR0 */
250 0x21, /* DR1 */
251 0x21, /* DR2 */
252 0x21, /* DR3 */
253 0x21, /* DR6 */
254 0x21, /* DR7 */
256 0x24, /* TR3 */
257 0x24, /* TR4 */
258 0x24, /* TR5 */
259 0x24, /* TR6 */
260 0x24, /* TR7 */
262 0x00, /* ST(0) */
263 0x00, /* ST(1) */
264 0x00, /* ST(2) */
265 0x00, /* ST(3) */
266 0x00, /* ST(4) */
267 0x00, /* ST(5) */
268 0x00, /* ST(6) */
269 0x00, /* ST(7) */
271 0x00, /* NOREG */
274 PRIVATE opcode_t rm[] =
276 0x05, /* BP */
277 0x03, /* BX */
278 0x07, /* DI */
279 0x06, /* SI */
281 0x00, /* EAX */
282 0x05, /* EBP */
283 0x03, /* EBX */
284 0x01, /* ECX */
285 0x07, /* EDI */
286 0x02, /* EDX */
287 0x06, /* ESI */
288 0x04, /* ESP */
290 0x00, /* AX */
291 0x01, /* CX */
292 0x02, /* DX */
293 0x04, /* SP */
295 0x04, /* AH */
296 0x00, /* AL */
297 0x07, /* BH */
298 0x03, /* BL */
299 0x05, /* CH */
300 0x01, /* CL */
301 0x06, /* DH */
302 0x02, /* DL */
304 0x01, /* CS */
305 0x03, /* DS */
306 0x00, /* ES */
307 0x04, /* FS */
308 0x05, /* GS */
309 0x02, /* SS */
311 0x00, /* CR0 */
312 0x00, /* CR2 */
313 0x00, /* CR3 */
315 0x00, /* DR0 */
316 0x00, /* DR1 */
317 0x00, /* DR2 */
318 0x00, /* DR3 */
319 0x00, /* DR6 */
320 0x00, /* DR7 */
322 0x00, /* TR3 */
323 0x00, /* TR4 */
324 0x00, /* TR5 */
325 0x00, /* TR6 */
326 0x00, /* TR7 */
328 0x00, /* ST(0) */
329 0x00, /* ST(1) */
330 0x00, /* ST(2) */
331 0x00, /* ST(3) */
332 0x00, /* ST(4) */
333 0x00, /* ST(5) */
334 0x00, /* ST(6) */
335 0x00, /* ST(7) */
337 0x04, /* null index reg for sib only */
340 PRIVATE opcode_t rmfunny[] =
342 0x06, /* BP */
343 0x07, /* BX */
344 0x05, /* DI */
345 0x04, /* SI */
348 PRIVATE opcode_t segoverride[] =
350 0x2E, /* CS */
351 0x3E, /* DS */
352 0x26, /* ES */
353 0x64, /* FS */
354 0x65, /* GS */
355 0x36, /* SS */
358 PRIVATE opcode_t ss[] = /* scale to ss bits */
360 0x00, /* x0, illegal */
361 0x00 << SS_SHIFT, /* x1 */
362 0x01 << SS_SHIFT, /* x2 */
363 0x00, /* x3, illegal */
364 0x02 << SS_SHIFT, /* x4 */
365 0x00, /* x5, illegal */
366 0x00, /* x6, illegal */
367 0x00, /* x7, illegal */
368 0x03 << SS_SHIFT, /* x8 */
371 PRIVATE unsigned char calljmp_kludge;
372 PRIVATE opcode_t direction;
373 PRIVATE bool_t fpreg_allowed;
374 PRIVATE opcode_t segword;
376 Values of segword:
377 BYTE_SEGWORD for byte ea's.
378 SEGMOV for segment registers
379 opcode for special registers
380 WORDBIT for other word and dword ea's
383 PRIVATE struct ea_s source;
384 PRIVATE struct ea_s source2;
385 PRIVATE struct ea_s target;
387 FORWARD void Eb P((struct ea_s *eap));
388 FORWARD void Ew P((struct ea_s *eap));
389 FORWARD void Ev P((struct ea_s *eap));
390 FORWARD void Ex P((struct ea_s *eap));
391 FORWARD void Gd P((struct ea_s *eap));
392 FORWARD void Gw P((struct ea_s *eap));
393 FORWARD void Gv P((struct ea_s *eap));
394 FORWARD void Gx P((struct ea_s *eap));
395 FORWARD void buildea P((struct ea_s *eap));
396 FORWARD void buildfloat P((void));
397 FORWARD void buildfreg P((void));
398 FORWARD void buildimm P((struct ea_s *eap, bool_pt signflag));
399 FORWARD void buildregular P((void));
400 FORWARD void buildsegword P((struct ea_s *eap));
401 FORWARD void buildunary P((opcode_pt opc));
402 FORWARD opsize_pt displsize P((struct ea_s *eap));
403 FORWARD reg_pt fpregchk P((void));
404 FORWARD bool_pt getaccumreg P((struct ea_s *eap));
405 FORWARD void getbinary P((void));
406 FORWARD bool_pt getdxreg P((struct ea_s *eap));
407 FORWARD void getea P((struct ea_s *eap));
408 FORWARD void getimmed P((struct ea_s *eap, count_t immed_count));
409 FORWARD void getindirect P((struct ea_s *eap));
410 FORWARD void getshift P((struct ea_s *eap));
411 FORWARD reg_pt indregchk P((reg_pt matchreg));
412 FORWARD void kgerror P((char * err_str));
413 FORWARD void lbranch P((int backamount));
414 FORWARD void notbytesize P((struct ea_s *eap));
415 FORWARD void notimmed P((struct ea_s *eap));
416 FORWARD void notindirect P((struct ea_s *eap));
417 FORWARD void notsegorspecreg P((struct ea_s *eap));
418 FORWARD void yesimmed P((struct ea_s *eap));
419 FORWARD void yes_samesize P((void));
421 PRIVATE void Eb(eap)
422 register struct ea_s *eap;
424 Ex(eap);
425 if (eap->size != 0x1)
427 #ifndef NODEFAULTSIZE
428 if (eap->size == 0x0)
429 eap->size = 0x1;
430 else
431 #endif
432 kgerror(ILL_SIZE);
436 PRIVATE void Ew(eap)
437 register struct ea_s *eap;
439 Ex(eap);
440 if (eap->size != 0x2)
442 #ifndef NODEFAULTSIZE
443 if (eap->size == 0x0)
444 eap->size = 0x2;
445 else
446 #endif
447 kgerror(ILL_SIZE);
451 PRIVATE void Ev(eap)
452 register struct ea_s *eap;
454 Ex(eap);
455 notbytesize(eap);
458 PRIVATE void Ex(eap)
459 register struct ea_s *eap;
461 getea(eap);
462 notimmed(eap);
463 notsegorspecreg(eap);
466 PRIVATE void Gd(eap)
467 register struct ea_s *eap;
469 Gx(eap);
470 if (eap->size != 0x4)
471 kgerror(ILL_SIZE);
474 PRIVATE void Gw(eap)
475 register struct ea_s *eap;
477 Gx(eap);
478 if (eap->size != 0x2)
479 kgerror(ILL_SIZE);
482 PRIVATE void Gv(eap)
483 register struct ea_s *eap;
485 Gx(eap);
486 notbytesize(eap);
489 PRIVATE void Gx(eap)
490 register struct ea_s *eap;
492 Ex(eap);
493 notindirect(eap);
496 PRIVATE void buildea(eap)
497 register struct ea_s *eap;
499 opsize_t asize;
501 ++mcount;
502 lastexp = eap->displ;
503 if (eap->indcount == 0x0)
504 postb = REG_MOD | rm[eap->base];
505 else
507 if (eap->base == NOREG)
509 if (eap->index == NOREG)
511 if ((asize = displsize(eap)) > 0x2)
512 postb = D32_RM;
513 else
514 postb = D16_RM;
516 else
518 asize = 0x4;
519 postb = SIB_NOBASE; /* for sib later */
522 else
524 if (eap->base > MAX16BITINDREG)
526 asize = 0x4;
527 postb = rm[eap->base];
529 else
531 asize = 0x2;
532 if (!(lastexp.data & UNDBIT) &&
533 !iswordorswordoffset(lastexp.offset))
534 error(ABOUNDS);
535 if (eap->index == NOREG)
536 postb = rmfunny[eap->base];
537 else if (eap->base <= MAX16BITINDREG)
538 postb = baseind16[eap->base + 0x4 * eap->index];
541 needcpu(asize==4?3:0);
542 if (asize != defsize)
543 aprefix = 0x67;
544 if (eap->base == NOREG)
545 mcount += asize;
546 else if (lastexp.data & (FORBIT | RELBIT | UNDBIT) ||
547 !is8bitsignedoffset(lastexp.offset))
549 postb |= MEM2_MOD;
550 mcount += asize;
552 else if (lastexp.offset != 0x0 ||
553 (eap->base == BPREG && eap->index == NOREG) ||
554 eap->base == EBPREG)
556 postb |= MEM1_MOD;
557 ++mcount;
559 if (asize > 0x2 && (eap->base == ESPREG || eap->index != NOREG))
561 sib = ss[eap->scale] |
562 (rm[eap->index] << INDEX_SHIFT) |
563 (postb & RM_MASK);
564 postb = (postb & MOD_MASK) | SIB_RM;
565 ++mcount;
570 PRIVATE void buildfloat()
572 if (mcount != 0x0)
574 buildea(&source);
575 oprefix = 0x0;
576 postb |= (opcode & 0x07) << REG_SHIFT;
577 opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4);
581 PRIVATE void buildfreg()
583 mcount += 0x2;
584 oprefix = 0x0;
585 postb = REG_MOD | ((opcode & 0x07) << REG_SHIFT) | (target.base - ST0REG);
586 opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4);
589 PRIVATE void buildimm(eap, signflag)
590 register struct ea_s *eap;
591 bool_pt signflag;
593 immadr = eap->displ;
594 immcount = eap->size;
595 if (!(immadr.data & (FORBIT | RELBIT | UNDBIT)))
597 if (immcount == 0x1)
599 if ((offset_t) (immadr.offset + 0x80) >= 0x180)
600 datatoobig();
602 else if (signflag && is8bitsignedoffset(immadr.offset))
604 opcode |= SIGNBIT;
605 immcount = 0x1;
607 else if (immcount == 0x2)
609 if ((offset_t) (immadr.offset + 0x8000L) >= 0x18000L)
610 datatoobig();
615 PRIVATE void buildregular()
617 if (mcount != 0x0)
619 buildea(&target);
620 postb |= regbits[source.base];
624 /* Check size and build segword. */
626 PRIVATE void buildsegword(eap)
627 register struct ea_s *eap;
629 if (eap->size == 0x0)
630 #ifdef NODEFAULTSIZE
631 kgerror(SIZE_UNK);
632 #else
633 eap->size = defsize;
634 #endif
635 if (eap->indcount != 0x0 || eap->base == NOREG)
637 segword = WORDBIT;
638 if (eap->size == 0x1)
639 segword = BYTE_SEGWORD;
641 else
642 segword = regsegword[eap->base];
645 PRIVATE void buildunary(opc)
646 opcode_pt opc;
648 if (mcount != 0x0)
650 buildea(&target);
651 postb |= opcode;
652 opcode = opc;
656 PRIVATE opsize_pt displsize(eap)
657 register struct ea_s *eap;
659 opsize_t asize;
661 asize = defsize;
662 if (!(eap->displ.data & UNDBIT))
664 if (asize > 0x2)
666 if (!(eap->displ.data & (FORBIT | RELBIT)) &&
667 iswordadr(eap->displ.offset))
668 asize = 0x2;
670 else if (!iswordorswordoffset(eap->displ.offset))
671 /* should really use iswordadr() */
672 /* but compiler generates signed offsets */
674 if (!(eap->displ.data & (FORBIT | RELBIT)))
675 asize = 0x4;
676 else if (pass2)
677 error(ABOUNDS);
680 return asize;
683 PRIVATE reg_pt fpregchk()
685 reg_pt fpreg;
687 fpreg_allowed = TRUE;
688 fpreg = regchk();
689 fpreg_allowed = FALSE;
690 if (fpreg != ST0REG)
691 return NOREG;
692 getsym();
693 if (sym == LPAREN)
695 getsym();
696 if (sym != INTCONST || (unsigned) number >= 0x8)
697 error(ILL_FP_REG);
698 else
700 fpreg += number;
701 getsym();
702 if (sym != RPAREN)
703 error(RPEXP);
704 else
705 getsym();
708 return fpreg;
711 PRIVATE bool_pt getaccumreg(eap)
712 register struct ea_s *eap;
714 if ((eap->base = regchk()) != AXREG && eap->base != ALREG
715 && eap->base != EAXREG)
716 return FALSE;
717 getsym();
718 if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize)
719 oprefix = 0x66;
720 return TRUE;
724 Get binary ea's in target & source (flipped if direction is set).
725 Put size in source if not already.
726 Initialise direction, segword, bump mcount.
729 PRIVATE void getbinary()
731 ++mcount;
732 getea(&target);
733 if (target.indcount == 0x0 && target.base == NOREG)
735 error(ILL_IMM_MODE);
736 target.base = AXREG;
737 target.size = defsize;
739 getcomma();
740 getea(&source);
741 if (source.size == 0x0)
742 source.size = target.size;
743 else if (target.size != 0x0 && target.size != source.size)
745 kgerror(MISMATCHED_SIZE);
746 return;
748 if (source.indcount == 0x0 && regsegword[target.base] < SEGMOV)
749 direction = 0x0;
750 else if (target.indcount == 0x0 && regsegword[source.base] < SEGMOV)
752 struct ea_s swap;
754 direction = TOREGBIT;
755 swap = source;
756 source = target;
757 target = swap;
759 else if (target.indcount != 0x0)
761 kgerror(ILL_IND_TO_IND);
762 return;
764 else
766 kgerror(ILL_SEG_REG);
767 return;
769 buildsegword(&source);
772 PRIVATE bool_pt getdxreg(eap)
773 register struct ea_s *eap;
775 if ((eap->base = regchk()) != DXREG)
776 return FALSE;
777 getsym();
778 return TRUE;
781 /* parse effective address */
784 Syntax is restrictive in that displacements must be in the right spots
785 and will not be added up.
787 optional size-type prefix, which is
788 BYTE
789 BYTE PTR
790 WORD
791 WORD PTR
792 DWORD
793 DWORD PTR
796 segreg
797 [scaled index]
798 where scaled index =
799 indreg
800 indreg*scale
801 indreg+indreg
802 indreg+indreg*scale
803 [scaled index+displ]
804 [scaled index-displ]
805 optional-immediate-prefix displ[scaled index]
806 [displ]
807 optional-imediate-prefix displ
808 (scaled index) -- anachronism
809 optional-imediate-prefix displ(scaled index) -- anachronism
812 PRIVATE void getea(eap)
813 register struct ea_s *eap;
815 bool_t leading_displ;
816 bool_t leading_immed;
817 register struct sym_s *symptr;
819 leading_immed = leading_displ = lastexp.data = eap->indcount
820 = lastexp.offset = 0x0;
821 eap->index = eap->base = NOREG;
822 eap->scale = 0x1;
823 eap->size = mnsize; /* 0x1 for byte ops, else 0x0 */
825 if (sym == IDENT)
827 if ((symptr = gsymptr)->type & MNREGBIT)
829 if (symptr->data & SIZEBIT)
831 getsym();
832 if (symptr->value_reg_or_op.op.opcode == 0x0)
833 eap->indcount = 0x2 - calljmp_kludge;
834 else
836 if (eap->size != 0x0)
838 if (eap->size != symptr->value_reg_or_op.op.opcode)
839 error(MISMATCHED_SIZE);
841 else
842 eap->size = symptr->value_reg_or_op.op.opcode;
843 if (eap->size > 0x1 && eap->size != defsize)
844 oprefix = 0x66;
845 if (sym == IDENT &&
846 (symptr = gsymptr)->type & MNREGBIT &&
847 symptr->data & SIZEBIT &&
848 symptr->value_reg_or_op.op.routine == PTROP)
850 getsym();
851 eap->indcount = 0x2 - calljmp_kludge;
856 if( last_pass == 1 )
857 if (!(symptr->type & (LABIT | MACBIT | MNREGBIT | VARBIT)))
858 symptr->data |= FORBIT; /* show seen in advance */
860 if ((eap->base = regchk()) != NOREG)
862 getsym();
863 if (eap->indcount != 0x0)
865 error(ILL_IND_PTR);
866 eap->indcount = 0x0;
868 if (eap->size != 0x0 && eap->size != regsize[eap->base])
869 error(MISMATCHED_SIZE);
870 if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize)
871 oprefix = 0x66;
872 eap->displ = lastexp;
873 needcpu(eap->size==4?3:0);
874 return;
876 if (sym != lindirect)
878 if (sym == IMMEDIATE || sym == STAR)
880 /* context-sensitive, STAR means signed immediate here */
881 leading_immed = TRUE;
882 getsym();
884 leading_displ = TRUE;
885 expres();
886 eap->displ = lastexp;
888 if (sym == lindirect)
890 getsym();
891 eap->indcount = 0x2 - calljmp_kludge;
892 if ((eap->base = indregchk((reg_pt) NOREG)) != NOREG)
894 if (eap->indcount == 0x0 && leading_displ)
895 error(IND_REQ);
896 getsym();
897 if (sym == ADDOP)
899 getsym();
900 if ((eap->index = indregchk(eap->base)) != NOREG)
901 getsym();
902 else
904 if (eap->indcount == 0x0)
905 error(IND_REQ);
906 if (leading_displ)
907 error(REPEATED_DISPL);
908 expres(); /* this eats ADDOP, SUBOP, MULOP */
911 if (sym == STAR)
913 needcpu(3);
914 /* context-sensitive, STAR means scaled here*/
915 if (eap->index == NOREG && eap->base == ESPREG)
917 error(INDEX_REG_EXP);
918 eap->base = EAXREG;
920 getsym();
921 factor();
922 chkabs();
923 if (!(lastexp.data & UNDBIT) && lastexp.offset != 0x1)
925 if (eap->base <= MAX16BITINDREG ||
926 (lastexp.offset != 0x2 && lastexp.offset != 0x4 &&
927 lastexp.offset != 0x8))
928 error(ILL_SCALE);
929 else
931 eap->scale = lastexp.offset;
932 if (eap->index == NOREG)
934 eap->index = eap->base;
935 eap->base = NOREG;
939 lastexp.data = lastexp.offset = 0x0;
941 if ((sym == ADDOP || sym == SUBOP))
943 if (eap->indcount == 0x0)
944 error(IND_REQ);
945 if (leading_displ)
946 error(REPEATED_DISPL);
947 expres();
950 else
952 if (leading_displ)
953 error(REPEATED_DISPL);
954 expres();
956 if (sym != rindirect)
957 error(rindexp);
958 else
959 getsym();
961 /* RDB */
962 else if (!leading_immed && defsize <= 0x2)
963 eap->indcount = 0x1; /* compatibility kludge */
964 if (!leading_displ)
965 eap->displ = lastexp;
967 needcpu(eap->size==4?3:0);
970 PRIVATE void getimmed(eap, immed_count)
971 struct ea_s *eap;
972 count_t immed_count;
974 getea(eap);
975 yesimmed(eap);
976 if (mcount != 0x0)
978 eap->size = immed_count;
979 buildimm(eap, FALSE);
983 PRIVATE void getindirect(eap)
984 register struct ea_s *eap;
986 getea(eap);
987 if (eap->indcount == 0x0)
988 kgerror(IND_REQ);
991 PRIVATE void getshift(eap)
992 register struct ea_s *eap;
994 getcomma();
995 getea(eap);
996 if (eap->base != CLREG)
997 yesimmed(eap);
1001 Check if current symbol is a compatible index register.
1002 Generate error if it is a reg but not a compatible index.
1003 Return register number (adjusted if necessary to a legal index) or NOREG.
1006 PRIVATE reg_pt indregchk(matchreg)
1007 reg_pt matchreg;
1009 reg_pt reg;
1011 if ((reg = regchk()) != NOREG)
1013 switch (matchreg)
1015 case BPREG:
1016 case BXREG:
1017 if (reg != DIREG && reg != SIREG)
1019 reg = SIREG;
1020 error(INDEX_REG_EXP);
1022 break;
1023 case DIREG:
1024 case SIREG:
1025 if (reg != BPREG && reg != BXREG)
1027 reg = BXREG;
1028 error(INDEX_REG_EXP);
1030 break;
1031 case NOREG:
1032 break;
1033 default:
1034 if (reg <= MAX16BITINDREG || reg == ESPREG)
1036 reg = EAXREG;
1037 error(INDEX_REG_EXP);
1039 break;
1041 if (reg > MAXINDREG && calljmp_kludge == 0x0)
1043 if (matchreg != NOREG)
1044 reg = EAXREG;
1045 else
1046 reg = BXREG;
1047 error(INDEX_REG_EXP);
1050 return reg;
1053 PRIVATE void kgerror(err_str)
1054 char * err_str;
1056 error(err_str);
1057 sprefix = oprefix = aprefix = mcount = 0x0;
1060 PRIVATE void lbranch(backamount)
1061 int backamount;
1063 mcount += defsize + 0x1;
1064 segadj();
1065 if (pass2)
1067 reldata();
1068 if (!(lastexp.data & (RELBIT | UNDBIT)))
1070 lastexp.offset = lastexp.offset - lc - lcjump;
1071 if ( last_pass<2 && backamount != 0x0 &&
1072 !(lastexp.data & IMPBIT) &&
1073 lastexp.offset + backamount < 0x80 + backamount)
1074 warning(SHORTB); /* -0x8? to 0x7F, warning */
1079 /* BCC (long branches emulated by short branch over & long jump) */
1081 PUBLIC void mbcc()
1083 getea(&target);
1084 if (target.indcount >= 0x2 || target.base != NOREG)
1085 kgerror(REL_REQ);
1086 else
1088 #ifdef iscpu
1089 if (iscpu(3))
1090 #else
1091 if (defsize != 0x2)
1092 #endif
1094 page = PAGE1_OPCODE;
1095 ++mcount;
1096 opcode += 0x10;
1097 lbranch(0x84);
1099 else
1101 aprefix = opcode ^ 0x1; /* kludged storage for short branch
1102 over */
1103 oprefix = defsize + 0x1;
1104 mcount += 0x2;
1105 opcode = JMP_OPCODE;
1106 lbranch(0x83);
1107 mcount -= 0x2;
1112 /* bswap r32 */
1114 PUBLIC void mbswap()
1116 needcpu(4);
1117 ++mcount;
1118 Gd(&target);
1119 opcode |= rm[target.base];
1122 /* BR, CALL, J, JMP */
1124 PUBLIC void mcall()
1126 opcode_pt far_diff;
1127 bool_t indirect;
1128 register struct sym_s *symptr;
1130 far_diff = 0x0;
1131 if (sym == IDENT && (symptr = gsymptr)->type & MNREGBIT &&
1132 symptr->data & SIZEBIT )
1134 if(symptr->value_reg_or_op.op.routine == FAROP)
1136 far_diff = 0x8;
1137 getsym();
1139 if(symptr->value_reg_or_op.op.routine == WORDOP &&
1140 opcode == JMP_SHORT_OPCODE)
1142 opcode = JMP_OPCODE;
1143 getsym();
1146 indirect = FALSE;
1148 if (asld_compatible && defsize <= 0x2)
1150 calljmp_kludge = 0x2;
1151 if (sym == INDIRECT)
1153 calljmp_kludge = 0x0;
1154 indirect = TRUE;
1155 getsym();
1158 getea(&target);
1159 if (indirect && target.indcount == 0x1)
1160 target.indcount = 0x2;
1161 calljmp_kludge = 0x0;
1162 if (sym == COLON)
1164 int tsize = target.size?target.size:defsize;
1165 if (opcode == JMP_SHORT_OPCODE)
1166 opcode = JMP_OPCODE;
1167 ++mcount;
1168 yesimmed(&target);
1169 getsym();
1170 getea(&source);
1171 yesimmed(&source);
1172 if (mcount != 0x0)
1174 if (opcode == JMP_OPCODE)
1175 opcode = 0xEA;
1176 else
1177 opcode = 0x9A;
1178 lastexp = source.displ;
1179 if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) &&
1180 tsize == 0x2 &&
1181 (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
1182 datatoobig();
1183 mcount += tsize;
1184 target.size = 0x2;
1185 buildimm(&target, FALSE);
1188 else if (target.indcount >= 0x2 || target.base != NOREG)
1190 ++mcount;
1191 notsegorspecreg(&target);
1192 if (target.indcount == 0)
1193 notbytesize(&target);
1194 if (mcount != 0x0)
1196 if (opcode == JMP_SHORT_OPCODE)
1197 opcode = JMP_OPCODE;
1198 buildea(&target);
1199 if (opcode == JMP_OPCODE)
1200 opcode = 0x20;
1201 else
1202 opcode = 0x10;
1203 postb |= opcode + far_diff;
1204 opcode = 0xFF;
1207 else if (opcode == JMP_SHORT_OPCODE)
1209 if (jumps_long &&
1210 ((pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) ||
1211 (last_pass==1)))
1213 opcode = JMP_OPCODE;
1214 lbranch(0x83);
1216 else
1218 lastexp = target.displ;
1219 if (lastexp.data & IMPBIT)
1221 error(NONIMPREQ);
1222 lastexp.data = FORBIT | UNDBIT;
1224 mshort2();
1227 else
1228 lbranch(opcode == JMP_OPCODE ? 0x83 : 0x0);
1231 /* CALLI, JMPI */
1233 PUBLIC void mcalli()
1235 bool_t indirect;
1237 ++mcount;
1238 indirect = FALSE;
1239 if (sym == INDIRECT)
1241 getsym();
1242 indirect = TRUE;
1244 getea(&target);
1245 if (target.indcount >= 0x2 || target.base != NOREG)
1246 indirect = TRUE;
1247 if (indirect)
1249 buildea(&target);
1250 if (opcode == 0xEA)
1251 opcode = 0x28;
1252 else
1253 opcode = 0x18;
1254 postb |= opcode;
1255 opcode = 0xFF;
1257 else
1259 int tsize = target.size?target.size:defsize;
1260 getcomma();
1261 getea(&source);
1262 yesimmed(&source);
1263 if (mcount != 0x0)
1265 lastexp = target.displ;
1266 if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) &&
1267 tsize == 0x2 &&
1268 (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
1270 tsize=4;
1271 if( tsize != defsize ) oprefix = 0x66;
1272 /* datatoobig(); */
1274 needcpu(tsize==4?3:0);
1275 mcount += tsize;
1276 source.size = 0x2;
1277 buildimm(&source, FALSE);
1282 /* DIV, IDIV, MUL */
1284 PUBLIC void mdivmul()
1286 if (getaccumreg(&source))
1288 ++mcount;
1289 getcomma();
1290 Ex(&target);
1291 yes_samesize();
1292 buildunary(0xF6 | regsegword[source.base]);
1294 else
1295 mnegnot();
1298 /* ENTER */
1300 PUBLIC void menter()
1302 ++mcount;
1303 getimmed(&target, 0x2);
1304 getcomma();
1305 getimmed(&source, 0x1);
1306 if (mcount != 0x0)
1308 mcount += 2;
1309 lastexp = target.displ; /* getimmed(&source) wiped it out */
1311 needcpu(1);
1314 /* arpl r/m16,r16 (Intel manual opcode chart wrongly says EwRw) */
1316 PUBLIC void mEwGw()
1318 ++mcount;
1319 Ew(&target);
1320 getcomma();
1321 Gw(&source);
1322 oprefix = 0x0;
1323 buildregular();
1326 /* [cmpxchg xadd] [r/m8,r8 r/m16,r16, r/m32,r32] */
1328 PUBLIC void mExGx()
1330 ++mcount;
1331 Ex(&target);
1332 getcomma();
1333 Gx(&source);
1334 yes_samesize();
1335 opcode |= segword;
1336 buildregular();
1339 PUBLIC void mf_inher()
1341 mcount += 0x2;
1342 postb = REG_MOD | (opcode & ~REG_MOD);
1343 opcode = ESCAPE_OPCODE_BASE | (opcode >> 0x6);
1344 if (opcode == ESCAPE_OPCODE_BASE)
1345 opcode = ESCAPE_OPCODE_BASE | 0x6; /* fix up encoding of fcompp */
1348 /* [fldenv fnsave fnstenv frstor] mem */
1350 PUBLIC void mf_m()
1352 ++mcount;
1353 getindirect(&source);
1354 if (source.size != 0x0)
1355 kgerror(ILL_SIZE);
1356 buildfloat();
1359 /* [fldcw fnstcw] mem2i */
1361 PUBLIC void mf_m2()
1363 ++mcount;
1364 getindirect(&source);
1365 if (source.size != 0x0 && source.size != 0x2)
1366 kgerror(ILL_SIZE);
1367 buildfloat();
1370 /* fnstsw [mem2i ax] */
1372 PUBLIC void mf_m2_ax()
1374 if (getaccumreg(&target))
1376 if (target.base != AXREG)
1377 kgerror(ILLREG);
1378 else
1380 opcode = 0x74;
1381 target.base = ST0REG; /* fake, really ax */
1382 buildfreg();
1385 else
1386 mf_m2();
1389 /* [fiadd ficom ficomp fidiv fidivr fimul fist fisub fisubr] [mem2i mem4i] */
1391 PUBLIC void mf_m2_m4()
1393 ++mcount;
1394 getindirect(&source);
1395 if (source.size == 0x0)
1396 kgerror(SIZE_UNK);
1397 else if (source.size == 0x2)
1398 opcode |= 0x40;
1399 else if (source.size != 0x4)
1400 kgerror(ILL_SIZE);
1401 buildfloat();
1404 /* [fild fistp] [mem2i mem4i mem8i] */
1406 PUBLIC void mf_m2_m4_m8()
1408 ++mcount;
1409 getindirect(&source);
1410 if (source.size == 0x0)
1411 kgerror(SIZE_UNK);
1412 else if (source.size == 0x2)
1413 opcode |= 0x40;
1414 else if (source.size == 0x8)
1415 opcode |= 0x45; /* low bits 0 -> 5 and 3 -> 7 */
1416 else if (source.size != 0x4)
1417 kgerror(ILL_SIZE);
1418 buildfloat();
1421 /* [fcom fcomp] [mem4r mem8r optional-st(i)] */
1423 PUBLIC void mf_m4_m8_optst()
1425 if (sym == EOLSYM)
1427 target.base = ST1REG;
1428 buildfreg();
1430 else
1431 mf_m4_m8_st();
1434 /* [fadd fdiv fdivr fmul fsub fsubr] [mem4r mem8r st,st(i) st(i),st] */
1436 PUBLIC void mf_m4_m8_stst()
1438 target.base = fpregchk();
1439 if (target.base != NOREG)
1441 getcomma();
1442 source.base = fpregchk();
1443 if (source.base == NOREG)
1445 error(FP_REG_REQ);
1446 source.base = ST0REG;
1448 if (target.base == ST0REG)
1449 target.base = source.base;
1450 else
1452 if (source.base != ST0REG)
1453 error(ILL_FP_REG_PAIR);
1454 opcode |= 0x40;
1455 if ((opcode & 0x07) >= 0x4)
1456 opcode ^= 0x01; /* weird swap of fdiv/fdivr, fsub/fsubr */
1458 buildfreg();
1460 else
1462 ++mcount;
1463 getindirect(&source);
1464 if (source.size == 0x0)
1465 kgerror(SIZE_UNK);
1466 else if (source.size == 0x8)
1467 opcode |= 0x40;
1468 else if (source.size != 0x4)
1469 kgerror(ILL_SIZE);
1470 buildfloat();
1474 /* fst [mem4r mem8r st(i)] */
1476 PUBLIC void mf_m4_m8_st()
1478 target.base = fpregchk();
1479 if (target.base != NOREG)
1481 if (opcode == FST_ENCODED)
1482 opcode |= 0x40;
1483 buildfreg();
1485 else
1487 ++mcount;
1488 getindirect(&source);
1489 if (source.size == 0x0)
1490 kgerror(SIZE_UNK);
1491 else if (source.size == 0x8)
1492 opcode |= 0x40;
1493 else if (source.size != 0x4)
1494 kgerror(ILL_SIZE);
1495 buildfloat();
1499 /* [fld fstp] [mem4r mem8r mem10r st(i)] */
1501 PUBLIC void mf_m4_m8_m10_st()
1503 target.base = fpregchk();
1504 if (target.base != NOREG)
1506 if (opcode == FSTP_ENCODED)
1507 opcode |= 0x40;
1508 buildfreg();
1510 else
1512 ++mcount;
1513 getindirect(&source);
1514 if (source.size == 0x0)
1515 kgerror(SIZE_UNK);
1516 else if (source.size == 0x8)
1517 opcode |= 0x40;
1518 else if (source.size == 0xA)
1519 opcode |= 0x25; /* low bits 0 -> 5 and 3 -> 7 */
1520 else if (source.size != 0x4)
1521 kgerror(ILL_SIZE);
1522 buildfloat();
1526 /* [fbld fbstp] mem10r */
1528 PUBLIC void mf_m10()
1530 ++mcount;
1531 getindirect(&source);
1532 if (source.size != 0xA)
1533 kgerror(ILL_SIZE);
1534 buildfloat();
1537 /* ffree st(i) */
1539 PUBLIC void mf_st()
1541 target.base = fpregchk();
1542 if (target.base == NOREG)
1543 kgerror(FP_REG_REQ);
1544 buildfreg();
1547 /* [fucom fucomp fxch] optional-st(i) */
1549 PUBLIC void mf_optst()
1551 if (sym == EOLSYM)
1553 target.base = ST1REG;
1554 buildfreg();
1556 else
1557 mf_st();
1560 /* [faddp fdivp fdivrp fmulp fsubp fsubrp] st(i),st */
1562 PUBLIC void mf_stst()
1564 target.base = fpregchk();
1565 if (target.base == NOREG)
1567 kgerror(FP_REG_REQ);
1568 return;
1570 getcomma();
1571 source.base = fpregchk();
1572 if (source.base == NOREG)
1574 kgerror(FP_REG_REQ);
1575 return;
1577 if (source.base != ST0REG)
1579 kgerror(ILL_FP_REG);
1580 return;
1582 buildfreg();
1585 PUBLIC void mf_w_inher()
1587 sprefix = WAIT_OPCODE;
1588 mf_inher();
1591 /* [fsave fstenv] mem */
1593 PUBLIC void mf_w_m()
1595 sprefix = WAIT_OPCODE;
1596 mf_m();
1599 /* fstcw mem2i */
1601 PUBLIC void mf_w_m2()
1603 sprefix = WAIT_OPCODE;
1604 mf_m2();
1607 /* fstsw [mem2i ax] */
1609 PUBLIC void mf_w_m2_ax()
1611 sprefix = WAIT_OPCODE;
1612 mf_m2_ax();
1615 /* ADC, ADD, AND, CMP, OR, SBB, SUB, XOR */
1617 PUBLIC void mgroup1()
1619 getbinary();
1620 notsegorspecreg(&source);
1621 if (mcount != 0x0)
1623 if (source.base == NOREG)
1625 if (target.indcount == 0x0 && (target.base == ALREG ||
1626 target.base == AXREG ||
1627 (target.base == EAXREG &&
1628 (source.displ.data & (FORBIT | RELBIT | UNDBIT) ||
1629 !is8bitsignedoffset(source.displ.offset)))))
1631 opcode |= 0x04 | segword;
1632 buildimm(&source, FALSE);
1634 else
1636 buildunary(0x80 | segword);
1637 buildimm(&source, TRUE);
1640 else
1642 opcode |= direction | segword;
1643 buildregular();
1648 /* RCL, RCR, ROL, ROR, SAL, SAR, SHL, SHR */
1650 PUBLIC void mgroup2()
1652 ++mcount;
1653 Ex(&target);
1654 buildsegword(&target);
1655 getshift(&source);
1656 if (mcount != 0x0)
1658 buildunary(0xD0 | segword);
1659 if (source.base == CLREG)
1660 opcode |= 0x2;
1661 else if (source.displ.offset != 0x1)
1663 needcpu(1);
1664 opcode -= 0x10;
1665 source.size = 0x1;
1666 buildimm(&source, FALSE);
1671 /* LLDT, LTR, SLDT, STR, VERR, VERW */
1673 PUBLIC void mgroup6()
1675 needcpu(2);
1676 ++mcount;
1677 Ew(&target);
1678 oprefix = 0x0;
1679 buildunary(0x0);
1682 /* INVLPG, LGDT, LIDT, LMSW, SGDT, SIDT, SMSW */
1684 PUBLIC void mgroup7()
1686 needcpu(2); /* I think INVLPG is actually 386 */
1687 ++mcount;
1688 if (opcode == 0x20 || opcode == 0x30)
1690 Ew(&target);
1691 oprefix = 0x0;
1693 else
1695 getindirect(&target);
1696 oprefix = 0x0;
1697 if (target.size != 0x0 && target.size != 0x6)
1698 error(MISMATCHED_SIZE); /* XXX - size 6 wrong for INVLPG? */
1700 buildunary(0x1);
1703 /* BT, BTR, BTS, BTC */
1705 PUBLIC void mgroup8()
1707 needcpu(3);
1708 ++mcount;
1709 Ev(&target);
1710 getcomma();
1711 /* Gv or Ib */
1712 getea(&source);
1713 notindirect(&source);
1714 notsegorspecreg(&source);
1715 if (mcount != 0x0)
1717 if (source.base == NOREG)
1719 buildunary(0xBA);
1720 source.size = 0x1;
1721 buildimm(&source, TRUE);
1723 else
1725 yes_samesize();
1726 opcode += 0x83;
1727 buildregular();
1732 /* BSF, BSR, LAR, LSL (Intel manual opcode chart wrongly says GvEw for L*) */
1734 PUBLIC void mGvEv()
1736 needcpu(2);
1737 ++mcount;
1738 Gv(&source);
1739 getcomma();
1740 Ev(&target);
1741 yes_samesize();
1742 buildregular();
1745 /* bound [r16,m16&16 r32,m32&32] */
1747 PUBLIC void mGvMa()
1749 ++mcount;
1750 Gv(&source);
1751 getcomma();
1752 getindirect(&target);
1753 yes_samesize();
1754 buildregular();
1757 /* LDS, LES, LFS, LGS, LSS */
1759 PUBLIC void mGvMp()
1761 ++mcount;
1762 Gv(&source);
1763 getcomma();
1764 getindirect(&target);
1765 if (target.size != 0x0 && target.size != 0x2 + source.size)
1766 error(MISMATCHED_SIZE);
1767 buildregular();
1770 /* IMUL */
1772 PUBLIC void mimul()
1774 ++mcount;
1775 Ex(&target);
1776 if (sym != COMMA)
1778 buildsegword(&target);
1779 buildunary(0xF6 | segword);
1780 return;
1782 getcomma();
1783 notindirect(&target);
1784 source = target; /* direction is swapped */
1785 getea(&target);
1786 notsegorspecreg(&target);
1787 yes_samesize();
1788 if (sym != COMMA && (target.indcount != 0x0 || target.base != NOREG))
1790 needcpu(3);
1791 page = PAGE1_OPCODE;
1792 ++mcount;
1793 opcode = 0xAF;
1794 buildregular();
1796 else
1798 if (sym == COMMA)
1800 getsym();
1801 getea(&source2);
1802 yesimmed(&source2);
1804 else
1806 source2 = target;
1807 target = source;
1809 source2.size = target.size;
1810 if (is8bitsignedoffset(source2.displ.offset))
1812 source2.size = 0x1;
1813 opcode = 0x6B;
1815 else
1817 source2.size = target.size;
1818 opcode = 0x69;
1820 buildregular();
1821 if (mcount != 0x0)
1822 buildimm(&source2, FALSE);
1826 /* IN */
1828 PUBLIC void min()
1830 ++mcount;
1831 if (opcode & WORDBIT) /* inw; ind not supported */
1832 mnsize = 0x2;
1833 if (sym == EOLSYM && mnsize != 0x0)
1834 target.size = mnsize;
1835 else
1837 if (getaccumreg(&target))
1839 if (mnsize != 0x0 && regsize[target.base] != mnsize)
1840 error(MISMATCHED_SIZE);
1841 getcomma();
1843 else
1844 target.size = regsize[target.base = mnsize < 0x2 ? ALREG : AXREG];
1845 opcode |= regsegword[target.base];
1846 if (!getdxreg(&source))
1848 getimmed(&source, 0x1);
1849 opcode -= 0x8;
1852 if (target.size > 0x1 && target.size != defsize)
1853 oprefix = 0x66;
1856 /* DEC, INC */
1858 PUBLIC void mincdec()
1860 ++mcount;
1861 Ex(&target);
1862 buildsegword(&target);
1863 if (target.indcount == 0x0 && segword == WORDBIT)
1864 opcode |= 0x40 | rm[target.base];
1865 else
1866 buildunary(0xFE | segword);
1869 /* CBW, CWD, CMPSW, INSW, IRET, LODSW, POPA, POPF, PUSHA, PUSHF */
1870 /* MOVSW, OUTSW, SCASW, STOSW */
1872 PUBLIC void minher16()
1874 minher();
1875 if (defsize != 0x2)
1876 oprefix = 0x66;
1879 /* CWDE, CDQ, CMPSD, INSD, IRETD, LODSD, POPAD, POPFD, PUSHAD, PUSHFD */
1880 /* MOVSD, OUTSD, SCASD, STOSD */
1882 PUBLIC void minher32()
1884 minher();
1885 if (defsize != 0x4)
1886 oprefix = 0x66;
1887 needcpu(3);
1890 /* AAD, AAM */
1892 PUBLIC void minhera()
1894 ++mcount;
1895 if (sym == EOLSYM)
1897 target.displ.offset = 0xA;
1898 target.size = 0x1;
1899 buildimm(&target, FALSE);
1901 else
1902 getimmed(&target, 0x1);
1905 /* INT */
1907 PUBLIC void mint()
1909 ++mcount;
1910 getimmed(&target, 0x1);
1911 if (!(immadr.data & (FORBIT | RELBIT | UNDBIT)) &&
1912 (opcode_t) immadr.offset == 0x3)
1914 immcount = 0x0;
1915 opcode = 0xCC;
1919 /* JCC */
1921 PUBLIC void mjcc()
1923 /* First look for j* near */
1924 if (sym == IDENT &&
1925 gsymptr->type & MNREGBIT &&
1926 gsymptr->data & SIZEBIT &&
1927 gsymptr->value_reg_or_op.op.routine == WORDOP &&
1928 opcode < 0x80)
1930 getsym();
1931 getea(&target);
1932 if (target.indcount >= 0x2 || target.base != NOREG)
1933 kgerror(REL_REQ);
1934 else
1936 needcpu(3);
1937 page = PAGE1_OPCODE;
1938 ++mcount;
1939 opcode += 0x10;
1940 lbranch(0x84);
1943 else if (!jumps_long || opcode > 0x80) /* above 0x80 means loop, not long */
1944 mshort();
1945 else /* mbcc */
1947 getea(&target);
1948 lastexp = target.displ;
1950 if ( (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) ||
1951 last_pass==1)
1953 if (target.indcount >= 0x2 || target.base != NOREG)
1954 kgerror(REL_REQ);
1956 aprefix = opcode ^ 0x1; /* kludged storage for short branch
1957 over */
1958 oprefix = defsize + 0x1;
1959 mcount += 0x2;
1960 opcode = JMP_OPCODE;
1961 lbranch(0x83);
1962 mcount -= 0x2;
1964 else
1966 /* 8 bit */
1967 if (lastexp.data & IMPBIT)
1969 error(NONIMPREQ);
1970 lastexp.data = FORBIT | UNDBIT;
1972 mshort2();
1977 /* JCXZ, JECXZ */
1979 PUBLIC void mjcxz()
1981 if (opcode != defsize)
1983 aprefix = 0x67;
1984 ++mcount; /* quick fix - mshort() needs to know */
1986 opcode = 0xE3;
1987 mshort();
1988 if (aprefix != 0x0)
1989 --mcount; /* quick fix - main routine bumps it again */
1992 /* LEA */
1994 PUBLIC void mlea()
1996 Gv(&source); /* back to front */
1997 getcomma();
1998 ++mcount;
1999 getindirect(&target);
2000 yes_samesize();
2001 buildregular();
2004 /* MOV */
2006 PUBLIC void mmov()
2008 getbinary();
2009 if (segword >= SEGMOV)
2011 oprefix = 0x0;
2012 notimmed(&target); /* target is actually the source */
2013 if (segword > SEGMOV) /* special reg */
2014 notindirect(&target);
2016 if (mcount != 0x0)
2018 if (target.base == NOREG && target.index == NOREG &&
2019 (source.base == ALREG || source.base == AXREG ||
2020 source.base == EAXREG))
2022 opcode = 0xA0 | (direction ^ TOREGBIT) | segword;
2023 lastexp = target.displ;
2024 if ((source.size = displsize(&target)) != defsize)
2025 aprefix = 0x67;
2026 mcount += source.size;
2027 needcpu(source.size==4?3:0);
2029 else if (source.base == NOREG)
2031 if (target.indcount == 0x0)
2032 opcode = 0xB0 | (segword << 0x3) | rm[target.base];
2033 else
2035 buildea(&target);
2036 opcode = 0xC6 | segword;
2038 buildimm(&source, FALSE);
2040 else
2042 if (isspecreg(source.base))
2044 needcpu(3);
2045 page = PAGE1_OPCODE;
2046 ++mcount;
2047 opcode = 0x0;
2049 opcode |= direction | segword;
2050 buildregular();
2055 /* MOVSX, MOVZX */
2057 PUBLIC void mmovx()
2059 ++mcount;
2060 Gv(&source);
2061 getcomma();
2062 Ex(&target);
2063 if (target.size == 0x0)
2064 kgerror(SIZE_UNK);
2065 if (target.size > 0x2)
2066 kgerror(ILL_SIZE);
2067 oprefix = 0x0;
2068 if (source.size != defsize)
2069 oprefix = 0x66;
2070 buildsegword(&target);
2071 opcode |= segword;
2072 buildregular();
2075 /* NEG, NOT */
2077 PUBLIC void mnegnot()
2079 ++mcount;
2080 Ex(&target);
2081 buildsegword(&target);
2082 buildunary(0xF6 | segword);
2085 /* OUT */
2087 PUBLIC void mout()
2089 ++mcount;
2090 if (opcode & WORDBIT) /* outw; outd not supported */
2091 mnsize = 0x2;
2092 if (sym == EOLSYM && mnsize != 0x0)
2093 source.size = mnsize;
2094 else
2096 if (!getdxreg(&target))
2098 getimmed(&target, 0x1);
2099 opcode -= 0x8;
2101 if (sym == COMMA)
2103 getsym();
2104 if (!getaccumreg(&source))
2105 kgerror(AL_AX_EAX_EXP);
2106 else if (mnsize != 0x0 && regsize[source.base] != mnsize)
2107 error(MISMATCHED_SIZE);
2109 else
2110 source.size = regsize[source.base = mnsize < 0x2 ? ALREG : AXREG];
2111 opcode |= regsegword[source.base];
2113 if (source.size > 0x1 && source.size != defsize)
2114 oprefix = 0x66;
2117 /* POP, PUSH */
2119 PUBLIC void mpushpop()
2121 opcode_t oldopcode;
2123 ++mcount;
2124 getea(&target);
2125 buildsegword(&target);
2126 notbytesize(&target);
2127 if ((oldopcode = opcode) == POP_OPCODE)
2129 notimmed(&target);
2130 if (target.base == CSREG)
2131 kgerror(ILL_SEG_REG);
2133 if (mcount != 0x0)
2135 if (target.indcount == 0x0)
2137 if (segword == SEGMOV)
2139 switch (target.base)
2141 case CSREG:
2142 opcode = 0x0E;
2143 break;
2144 case DSREG:
2145 opcode = 0x1E;
2146 break;
2147 case ESREG:
2148 opcode = 0x06;
2149 break;
2150 case SSREG:
2151 opcode = 0x16;
2152 break;
2153 case FSREG:
2154 opcode = 0xA0;
2155 page = PAGE1_OPCODE;
2156 ++mcount;
2157 break;
2158 case GSREG:
2159 opcode = 0xA8;
2160 page = PAGE1_OPCODE;
2161 ++mcount;
2162 break;
2164 if (oldopcode == POP_OPCODE)
2165 ++opcode;
2167 else if (target.base != NOREG)
2169 opcode = 0x50 | rm[target.base];
2170 if (oldopcode == POP_OPCODE)
2171 opcode |= 0x8;
2173 else
2175 opcode = 0x68;
2176 if (oldopcode == POP_OPCODE)
2177 ++opcode;
2178 buildimm(&target, TRUE);
2181 else
2183 buildea(&target);
2184 if (oldopcode == PUSH_OPCODE)
2185 postb |= 0x6 << REG_SHIFT;
2190 /* RET, RETF */
2192 PUBLIC void mret()
2194 ++mcount;
2195 if (sym != EOLSYM)
2197 --opcode;
2198 getimmed(&target, 0x2);
2202 /* SEG CS/DS/ES/FS/GS/SS */
2204 PUBLIC void mseg()
2206 reg_pt reg;
2208 if (regsegword[reg = regchk()] != SEGMOV)
2209 error(SEG_REG_REQ);
2210 else
2212 getsym();
2213 ++mcount;
2214 opcode = (segoverride - CSREG)[reg];
2218 /* SETCC */
2220 PUBLIC void msetcc()
2222 ++mcount;
2223 Eb(&target);
2224 if (mcount != 0x0)
2225 buildea(&target);
2228 /* SHLD, SHRD */
2230 PUBLIC void mshdouble()
2232 needcpu(3);
2233 ++mcount;
2234 Ev(&target);
2235 getcomma();
2236 Gv(&source);
2237 yes_samesize();
2238 buildregular();
2239 getshift(&source2);
2240 lastexp = target.displ; /* getshift() wiped it out */
2241 if (mcount != 0x0)
2243 if (source2.base == CLREG)
2244 opcode |= 0x1;
2245 else
2247 source2.size = 0x1;
2248 buildimm(&source2, FALSE);
2254 TEST
2255 Similar to the regular group1 operators.
2256 It does not allow the sign extended immediate byte forms
2257 and does not use the relevant direction bit.
2260 PUBLIC void mtest()
2262 getbinary();
2263 notsegorspecreg(&source);
2264 if (source.base == NOREG)
2266 if (mcount != 0x0)
2268 if (target.indcount == 0x0
2269 && (target.base == ALREG || target.base == AXREG
2270 || target.base == EAXREG))
2271 opcode = 0xA8 | segword;
2272 else
2274 buildea(&target);
2275 opcode = 0xF6 | segword;
2278 buildimm(&source, FALSE);
2280 else
2282 opcode |= segword;
2283 buildregular();
2288 XCHG
2289 Similar to the regular group1 operators.
2290 It does not allow any of the immediate forms
2291 and does not use the irrelevant direction bit.
2294 PUBLIC void mxchg()
2296 getbinary();
2297 notimmed(&source);
2298 notsegorspecreg(&source);
2299 if (target.indcount == 0x0)
2301 if (target.base == AXREG || target.base == EAXREG)
2303 opcode = 0x90 + rm[source.base];
2304 return;
2306 if (source.base == AXREG || source.base == EAXREG)
2308 opcode = 0x90 + rm[target.base];
2309 return;
2312 opcode |= segword;
2313 buildregular();
2316 PRIVATE void notbytesize(eap)
2317 register struct ea_s *eap;
2319 if (eap->size == 0x1)
2320 kgerror(ILL_SIZE);
2323 PRIVATE void notimmed(eap)
2324 register struct ea_s *eap;
2326 if (eap->indcount == 0x0 && eap->base == NOREG)
2327 kgerror(ILL_IMM_MODE);
2330 PRIVATE void notindirect(eap)
2331 register struct ea_s *eap;
2333 if (eap->indcount != 0x0)
2334 kgerror(ILL_IND);
2337 PRIVATE void notsegorspecreg(eap)
2338 register struct ea_s *eap;
2340 if (regsegword[eap->base] >= SEGMOV)
2341 kgerror(ILLREG);
2344 PRIVATE void yesimmed(eap)
2345 register struct ea_s *eap;
2347 if (eap->indcount == 0x1)
2348 eap->indcount = 0x0;
2349 if (eap->indcount != 0x0 || eap->base != NOREG)
2350 kgerror(IMM_REQ);
2353 PRIVATE void yes_samesize()
2355 if (target.size == 0x0)
2356 target.size = source.size;
2357 else if (source.size != 0x0 && target.size != source.size)
2358 kgerror(MISMATCHED_SIZE);
2361 #endif /* I80386 */
2363 #ifdef MC6809
2365 /* 6809 opcode constants */
2367 /* bits for indexed addressing */
2369 #define INDIRECTBIT 0x10
2370 #define INDEXBIT 0x80 /* except 5 bit offset */
2371 #define PCRELBIT 0x04 /* PC relative (in certain cases) */
2372 #define RRBITS 0x60 /* register select bits */
2374 PRIVATE opcode_t rrindex[] = /* register and index bits for indexed adr */
2376 0x60 | INDEXBIT, /* S */
2377 0x40 | INDEXBIT, /* U */
2378 0x00 | INDEXBIT, /* X */
2379 0x20 | INDEXBIT, /* Y */
2380 PCRELBIT | INDEXBIT, /* PC */
2383 PRIVATE opcode_t pushpull[] = /* push/pull codes */
2385 0x40, /* S */
2386 0x40, /* U */
2387 0x10, /* X */
2388 0x20, /* Y */
2389 0x80, /* PC */
2390 0x02, /* A */
2391 0x04, /* B */
2392 0x01, /* CC */
2393 0x08, /* DP */
2394 0x06, /* D */
2397 PRIVATE opcode_t tfrexg1[] = /* transfer/exchange codes for source reg */
2399 0x40, /* S */
2400 0x30, /* U */
2401 0x10, /* X */
2402 0x20, /* Y */
2403 0x50, /* PC */
2404 0x80, /* A */
2405 0x90, /* B */
2406 0xA0, /* CC */
2407 0xB0, /* DP */
2408 0x00, /* D */
2411 PRIVATE opcode_t tfrexg2[] = /* transfer/exchange codes for target reg */
2413 0x04, /* S */
2414 0x03, /* U */
2415 0x01, /* X */
2416 0x02, /* Y */
2417 0x05, /* PC */
2418 0x08, /* A */
2419 0x09, /* B */
2420 0x0A, /* CC */
2421 0x0B, /* DP */
2422 0x00, /* D */
2425 FORWARD void checkpostinc P((void));
2426 FORWARD void doaltind P((void));
2427 FORWARD void do1altind P((void));
2428 FORWARD void fixupind P((void));
2429 FORWARD void getindexnopost P((void));
2430 FORWARD void inderror P((char * err_str));
2431 FORWARD reg_pt indreg P((reg_pt maxindex));
2432 FORWARD void predec1 P((void));
2433 FORWARD void sustack P((reg_pt stackreg));
2435 PRIVATE void checkpostinc()
2437 if (sym == ADDOP)
2439 if (postb & INDIRECTBIT)
2440 inderror(ILLMOD); /* single-inc indirect illegal */
2441 else
2443 lastexp.offset &= 0xFF00; /* for printing if postbyte is 0: ,X+ */
2444 getsym();
2447 else if (sym == POSTINCOP)
2449 postb |= 0x1;
2450 getsym();
2452 else
2453 postb |= 0x4;
2454 fixupind();
2457 /* common code for all-mode ops, alterable-mode ops, indexed ops */
2459 PRIVATE void doaltind()
2461 mcount += 0x2;
2462 if (sym == LBRACKET)
2464 postb = INDIRECTBIT;
2465 getsym();
2466 do1altind();
2467 if (sym != RBRACKET)
2468 error(RBEXP);
2470 else
2471 do1altind();
2474 PRIVATE void do1altind()
2476 bool_t byteflag; /* set if direct or short indexed adr forced */
2477 char *oldlineptr;
2478 char *oldsymname;
2479 reg_pt reg;
2480 bool_t wordflag; /* set if extended or long indexed adr forced*/
2482 if ((reg = regchk()) != NOREG)
2484 switch (reg)
2486 case AREG:
2487 postb |= 0x86;
2488 break;
2489 case BREG:
2490 postb |= 0x85;
2491 break;
2492 case DREG:
2493 postb |= 0x8B;
2494 break;
2495 default:
2496 if (indreg(MAXINDREG) != NOREG)
2497 checkpostinc();
2498 return;
2500 getsym();
2501 if (sym != COMMA)
2502 inderror(COMEXP);
2503 else
2504 getindexnopost();
2505 return;
2507 else if (sym == SUBOP) /* could be -R or - in expression */
2509 oldlineptr = lineptr; /* save state */
2510 oldsymname = symname;
2511 getsym();
2512 reg = regchk();
2513 lineptr = oldlineptr;
2514 symname = oldsymname;
2515 if (reg != NOREG)
2517 predec1(); /* it's -R */
2518 return;
2520 sym = SUBOP;
2522 else if (sym == COMMA)
2524 postb |= INDEXBIT;
2525 getsym();
2526 if (sym == SUBOP)
2528 predec1();
2529 return;
2531 else if (sym != PREDECOP)
2533 if (indreg(MAXINDREG) != NOREG)
2534 checkpostinc();
2535 return;
2538 if (sym == PREDECOP)
2540 postb |= 0x83;
2541 getindexnopost();
2542 return;
2545 /* should have expression */
2547 wordflag = byteflag = FALSE;
2548 if (sym == LESSTHAN)
2550 /* context-sensitive, LESSTHAN means byte-sized here */
2551 byteflag = TRUE;
2552 getsym();
2554 else if (sym == GREATERTHAN)
2556 /* context-sensitive, GREATERTHAN means word-sized here */
2557 wordflag = TRUE;
2558 getsym();
2560 expres();
2561 if (sym == COMMA)
2562 { /* offset from register */
2563 getsym();
2564 if ((reg = indreg(PCREG)) == NOREG)
2565 return;
2566 postb |= 0x8; /* default 8 bit offset */
2567 if (reg == PCREG)
2569 reldata();
2570 if (!(lastexp.data & (RELBIT | UNDBIT)))
2572 lastexp.offset = lastexp.offset - lc;
2573 if (page != 0x0)
2574 lastexp.offset -= 0x4; /* extra for instruction */
2575 else
2576 lastexp.offset -= 0x3; /* 3 byte instruction
2577 assuming 8 bit offset */
2580 if (byteflag)
2582 if (!(lastexp.data & (RELBIT | UNDBIT)) &&
2583 !is8bitsignedoffset(lastexp.offset))
2584 error(ABOUNDS); /* forced short form is impossible */
2585 ++mcount;
2587 else if (wordflag || lastexp.data & (FORBIT | RELBIT | UNDBIT) ||
2588 !is8bitsignedoffset(lastexp.offset))
2589 { /* 16 bit offset */
2590 if (postb & PCRELBIT && !(lastexp.data & RELBIT))
2591 --lastexp.offset; /* instruction 1 longer than already
2592 allowed */
2593 postb |= 0x1;
2594 mcount += 0x2;
2596 else if (!(postb & PCRELBIT) &&
2597 (offset_t) (lastexp.offset + 0x10) < 0x20 &&
2598 !(postb & INDIRECTBIT && lastexp.offset != 0x0))
2599 { /* 5 bit offset */
2600 postb &= RRBITS | INDIRECTBIT;
2601 if (lastexp.offset == 0x0)
2602 postb |= 0x84; /* index with zero offset */
2603 else
2604 postb |= (lastexp.offset & 0x1F);
2606 else /* 8 bit offset */
2607 ++mcount;
2608 fixupind();
2610 else if (postb & INDIRECTBIT)
2611 { /* extended indirect */
2612 postb = 0x9F;
2613 mcount += 0x2;
2614 fixupind();
2616 else if (postb & INDEXBIT)
2617 inderror(ILLMOD); /* e.g. LEAX $10 */
2618 else
2620 if (byteflag || (!wordflag && !(lastexp.data & (FORBIT | RELBIT)) &&
2621 (lastexp.offset >> 0x8) == dirpag))
2622 { /* direct addressing */
2623 if (opcode >= 0x80)
2624 opcode |= 0x10;
2626 else /* extended addressing */
2628 if (opcode < 0x80)
2629 opcode |= 0x70;
2630 else
2631 opcode |= 0x30;
2632 ++mcount;
2633 if (pass2 && (opcode == JSR_OPCODE || opcode == JMP_OPCODE) &&
2634 !(lastexp.data & IMPBIT) &&
2635 lastexp.offset + (0x81 - 0x3) < 0x101)
2636 /* JSR or JMP could be done with BSR or BRA */
2637 warning(SHORTB);
2642 PRIVATE void fixupind()
2644 if ((opcode & 0x30) == 0x0) /* change all but LEA opcodes */
2646 if (opcode < 0x80)
2647 opcode |= 0x60;
2648 else
2649 opcode |= 0x20;
2653 PRIVATE void getindexnopost()
2655 getsym();
2656 if (indreg(MAXINDREG) != NOREG)
2657 fixupind();
2660 PRIVATE void inderror(err_str)
2661 char * err_str;
2663 error(err_str);
2664 if (postb & INDIRECTBIT)
2665 sym = RBRACKET; /* fake right bracket to kill further errors */
2666 fixupind();
2669 /* check current symbol is an index register (possibly excepting PC) */
2670 /* if so, modify postbyte RR and INDEXBIT for it, get next sym, return TRUE */
2671 /* otherwise generate error, return FALSE */
2673 PRIVATE reg_pt indreg(maxindex)
2674 reg_pt maxindex;
2676 reg_pt reg;
2678 if ((reg = regchk()) == NOREG)
2679 inderror(IREGEXP);
2680 else if (reg > maxindex)
2682 inderror(ILLREG);
2683 reg = NOREG;
2685 else
2687 postb |= rrindex[reg];
2688 getsym();
2690 return reg;
2693 /* all-mode ops */
2695 PUBLIC void mall()
2697 if (sym == IMMEDIATE)
2698 mimmed();
2699 else
2700 malter();
2703 /* alterable mode ops */
2705 PUBLIC void malter()
2707 postb = 0x0; /* not yet indexed or indirect */
2708 doaltind();
2711 /* indexed mode ops */
2713 PUBLIC void mindex()
2715 postb = INDEXBIT; /* indexed but not yet indirect */
2716 doaltind();
2719 /* immediate ops */
2721 PUBLIC void mimmed()
2723 opcode_t nybble;
2725 mcount += 0x2;
2726 if (sym != IMMEDIATE)
2727 error(ILLMOD);
2728 else
2730 if (opcode >= 0x80 && ((nybble = opcode & 0xF) == 0x3 ||
2731 nybble == 0xC || nybble >= 0xE))
2732 ++mcount; /* magic for long immediate */
2733 symexpres();
2734 if (pass2 && mcount <= 0x2)
2736 chkabs();
2737 checkdatabounds();
2742 /* long branches */
2744 PUBLIC void mlong()
2746 mcount += 0x3; /* may be 0x0 or 0x1 here */
2747 expres();
2748 segadj();
2749 if (pass2)
2751 reldata();
2752 if (!(lastexp.data & (RELBIT | UNDBIT)))
2754 lastexp.offset = lastexp.offset - lc - lcjump;
2755 if ( last_pass<2 && !(lastexp.data & IMPBIT) &&
2756 lastexp.offset + 0x81 < 0x101)
2757 warning(SHORTB); /* -0x81 to 0x7F, warning */
2762 /* PSHS and PULS */
2764 PUBLIC void msstak()
2766 sustack(SREG);
2769 /* TFR and EXG */
2771 PUBLIC void mswap()
2773 reg_pt reg;
2775 mcount = 0x2;
2776 if ((reg = regchk()) == NOREG)
2777 error(REGEXP);
2778 else
2780 postb = tfrexg1[reg];
2781 getsym();
2782 if (sym != COMMA)
2783 error(COMEXP);
2784 else
2786 getsym();
2787 if ((reg = regchk()) == NOREG)
2788 error(REGEXP);
2789 else if ((postb |= tfrexg2[reg])
2790 & 0x88 && (postb & 0x88) != 0x88)
2791 error(ILLREG); /* registers not of same size */
2796 /* PSHU and PULU */
2798 PUBLIC void mustak()
2800 sustack(UREG);
2803 PRIVATE void predec1()
2805 if (postb & INDIRECTBIT)
2806 inderror(ILLMOD); /* single-dec indirect illegal */
2807 else
2809 postb |= 0x82;
2810 getindexnopost();
2814 /* common routine for PSHS/PULS/PSHU/PULU */
2816 PRIVATE void sustack(stackreg)
2817 reg_pt stackreg;
2819 reg_pt reg;
2821 mcount = 0x2;
2822 while ((reg = regchk()) != NOREG)
2824 if (reg == stackreg)
2826 error(ILLREG); /* cannot stack self */
2827 break;
2829 postb |= pushpull[reg];
2830 getsym();
2831 if (sym != COMMA)
2832 break;
2833 getsym();
2837 #endif /* MC6809 */
2839 /* routines common to all processors */
2841 PUBLIC void getcomma()
2843 if (sym != COMMA)
2844 error(COMEXP);
2845 else
2846 getsym();
2849 /* inherent ops */
2851 /* for I80386 */
2852 /* AAA, AAS, CLC, CLD, CLI, CLTS, CMC, CMPSB, DAA, DAS, HLT, INTO, INSB, */
2853 /* INVD, */
2854 /* LAHF, LEAVE, LOCK, LODSB, MOVSB, NOP, OUTSB, REP, REPE, REPNE, REPNZ, */
2855 /* REPZ, SAHF, SCASB, STC, STD, STI, STOSB, WAIT, WBINVD */
2857 PUBLIC void minher()
2859 ++mcount;
2862 /* short branches */
2864 PUBLIC void mshort()
2866 nonimpexpres();
2867 mshort2();
2870 PRIVATE void mshort2()
2872 mcount += 0x2;
2873 if (pass2)
2875 reldata();
2876 if (lastexp.data & RELBIT)
2877 showrelbad();
2878 else if (!(lastexp.data & UNDBIT))
2880 lastexp.offset = lastexp.offset - lc - mcount;
2881 if (!is8bitsignedoffset(lastexp.offset))
2882 error(ABOUNDS);
2887 /* check if current symbol is a register, return register number or NOREG */
2889 PRIVATE reg_pt regchk()
2891 register struct sym_s *symptr;
2893 if (sym == IDENT)
2895 if ((symptr = gsymptr)->type & MNREGBIT)
2897 if (symptr->data & REGBIT)
2899 int regno = symptr->value_reg_or_op.reg;
2900 #ifdef I80386
2901 if (regno == ST0REG && !fpreg_allowed)
2902 error(FP_REG_NOT_ALLOWED);
2904 /* Check cpu */
2905 needcpu((regno==FSREG||regno==GSREG)?3:0);
2906 needcpu((regno>=EAXREG && regno<=ESPREG)?3:0);
2907 needcpu((regno>=CR0REG && regno<=TR7REG)?3:0);
2908 #endif
2909 return regno;
2912 else
2913 if( last_pass == 1 )
2914 if (!(symptr->type & (LABIT | MACBIT | VARBIT)))
2915 symptr->data |= FORBIT; /* show seen in advance */
2917 return NOREG;
2920 /* convert lastexp.data for PC relative */
2922 PRIVATE void reldata()
2924 if ((lastexp.data ^ lcdata) & (IMPBIT | RELBIT | SEGM))
2926 if ((lastexp.data ^ lcdata) & RELBIT)
2927 showrelbad(); /* rel - abs is weird, abs - rel is bad */
2928 else
2930 pcrflag = OBJ_R_MASK;
2931 lastexp.data = (lcdata & ~SEGM) | lastexp.data | RELBIT;
2932 /* segment is that of lastexp.data */
2935 else /* same file, segment and relocation */
2936 lastexp.data = (lastexp.data | lcdata) & ~(RELBIT | SEGM);
2939 PRIVATE void segadj()
2941 if ((lastexp.data & UNDBIT) && textseg >= 0 )
2943 lastexp.sym->data &= ~SEGM;
2944 lastexp.sym->data |= (lcdata & SEGM);