1 /* mops.c - handle pseudo-ops */
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));
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
33 #define INDEX_MASK 0x38
37 # define MEM0_MOD 0x00
38 # define MEM1_MOD 0x40
39 # define MEM2_MOD 0x80
46 # define SIB_NOBASE 0x05
48 #define SREG_MASK 0x38
58 PRIVATE opcode_t baseind16
[] =
60 0x00, /* BP + BP, illegal */
61 0x00, /* BX + BP, illegal */
64 0x00, /* BP + BX, illegal */
65 0x00, /* BX + BX, illegal */
70 0x00, /* DI + DI, illegal */
71 0x00, /* SI + DI, illegal */
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
[] =
208 PRIVATE opcode_t regsegword
[] =
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 */
274 PRIVATE opcode_t rm
[] =
337 0x04, /* null index reg for sib only */
340 PRIVATE opcode_t rmfunny
[] =
348 PRIVATE opcode_t segoverride
[] =
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
;
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));
422 register struct ea_s
*eap
;
425 if (eap
->size
!= 0x1)
427 #ifndef NODEFAULTSIZE
428 if (eap
->size
== 0x0)
437 register struct ea_s
*eap
;
440 if (eap
->size
!= 0x2)
442 #ifndef NODEFAULTSIZE
443 if (eap
->size
== 0x0)
452 register struct ea_s
*eap
;
459 register struct ea_s
*eap
;
463 notsegorspecreg(eap
);
467 register struct ea_s
*eap
;
470 if (eap
->size
!= 0x4)
475 register struct ea_s
*eap
;
478 if (eap
->size
!= 0x2)
483 register struct ea_s
*eap
;
490 register struct ea_s
*eap
;
496 PRIVATE
void buildea(eap
)
497 register struct ea_s
*eap
;
502 lastexp
= eap
->displ
;
503 if (eap
->indcount
== 0x0)
504 postb
= REG_MOD
| rm
[eap
->base
];
507 if (eap
->base
== NOREG
)
509 if (eap
->index
== NOREG
)
511 if ((asize
= displsize(eap
)) > 0x2)
519 postb
= SIB_NOBASE
; /* for sib later */
524 if (eap
->base
> MAX16BITINDREG
)
527 postb
= rm
[eap
->base
];
532 if (!(lastexp
.data
& UNDBIT
) &&
533 !iswordorswordoffset(lastexp
.offset
))
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
)
544 if (eap
->base
== NOREG
)
546 else if (lastexp
.data
& (FORBIT
| RELBIT
| UNDBIT
) ||
547 !is8bitsignedoffset(lastexp
.offset
))
552 else if (lastexp
.offset
!= 0x0 ||
553 (eap
->base
== BPREG
&& eap
->index
== NOREG
) ||
559 if (asize
> 0x2 && (eap
->base
== ESPREG
|| eap
->index
!= NOREG
))
561 sib
= ss
[eap
->scale
] |
562 (rm
[eap
->index
] << INDEX_SHIFT
) |
564 postb
= (postb
& MOD_MASK
) | SIB_RM
;
570 PRIVATE
void buildfloat()
576 postb
|= (opcode
& 0x07) << REG_SHIFT
;
577 opcode
= ESCAPE_OPCODE_BASE
| ((opcode
& 0x70) >> 0x4);
581 PRIVATE
void buildfreg()
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
;
594 immcount
= eap
->size
;
595 if (!(immadr
.data
& (FORBIT
| RELBIT
| UNDBIT
)))
599 if ((offset_t
) (immadr
.offset
+ 0x80) >= 0x180)
602 else if (signflag
&& is8bitsignedoffset(immadr
.offset
))
607 else if (immcount
== 0x2)
609 if ((offset_t
) (immadr
.offset
+ 0x8000L
) >= 0x18000L
)
615 PRIVATE
void buildregular()
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)
635 if (eap
->indcount
!= 0x0 || eap
->base
== NOREG
)
638 if (eap
->size
== 0x1)
639 segword
= BYTE_SEGWORD
;
642 segword
= regsegword
[eap
->base
];
645 PRIVATE
void buildunary(opc
)
656 PRIVATE opsize_pt
displsize(eap
)
657 register struct ea_s
*eap
;
662 if (!(eap
->displ
.data
& UNDBIT
))
666 if (!(eap
->displ
.data
& (FORBIT
| RELBIT
)) &&
667 iswordadr(eap
->displ
.offset
))
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
)))
683 PRIVATE reg_pt
fpregchk()
687 fpreg_allowed
= TRUE
;
689 fpreg_allowed
= FALSE
;
696 if (sym
!= INTCONST
|| (unsigned) number
>= 0x8)
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
)
718 if ((eap
->size
= regsize
[eap
->base
]) > 0x1 && eap
->size
!= defsize
)
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()
733 if (target
.indcount
== 0x0 && target
.base
== NOREG
)
737 target
.size
= defsize
;
741 if (source
.size
== 0x0)
742 source
.size
= target
.size
;
743 else if (target
.size
!= 0x0 && target
.size
!= source
.size
)
745 kgerror(MISMATCHED_SIZE
);
748 if (source
.indcount
== 0x0 && regsegword
[target
.base
] < SEGMOV
)
750 else if (target
.indcount
== 0x0 && regsegword
[source
.base
] < SEGMOV
)
754 direction
= TOREGBIT
;
759 else if (target
.indcount
!= 0x0)
761 kgerror(ILL_IND_TO_IND
);
766 kgerror(ILL_SEG_REG
);
769 buildsegword(&source
);
772 PRIVATE bool_pt
getdxreg(eap
)
773 register struct ea_s
*eap
;
775 if ((eap
->base
= regchk()) != DXREG
)
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
805 optional-immediate-prefix displ[scaled index]
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
;
823 eap
->size
= mnsize
; /* 0x1 for byte ops, else 0x0 */
827 if ((symptr
= gsymptr
)->type
& MNREGBIT
)
829 if (symptr
->data
& SIZEBIT
)
832 if (symptr
->value_reg_or_op
.op
.opcode
== 0x0)
833 eap
->indcount
= 0x2 - calljmp_kludge
;
836 if (eap
->size
!= 0x0)
838 if (eap
->size
!= symptr
->value_reg_or_op
.op
.opcode
)
839 error(MISMATCHED_SIZE
);
842 eap
->size
= symptr
->value_reg_or_op
.op
.opcode
;
843 if (eap
->size
> 0x1 && eap
->size
!= defsize
)
846 (symptr
= gsymptr
)->type
& MNREGBIT
&&
847 symptr
->data
& SIZEBIT
&&
848 symptr
->value_reg_or_op
.op
.routine
== PTROP
)
851 eap
->indcount
= 0x2 - calljmp_kludge
;
857 if (!(symptr
->type
& (LABIT
| MACBIT
| MNREGBIT
| VARBIT
)))
858 symptr
->data
|= FORBIT
; /* show seen in advance */
860 if ((eap
->base
= regchk()) != NOREG
)
863 if (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
)
872 eap
->displ
= lastexp
;
873 needcpu(eap
->size
==4?3:0);
876 if (sym
!= lindirect
)
878 if (sym
== IMMEDIATE
|| sym
== STAR
)
880 /* context-sensitive, STAR means signed immediate here */
881 leading_immed
= TRUE
;
884 leading_displ
= TRUE
;
886 eap
->displ
= lastexp
;
888 if (sym
== lindirect
)
891 eap
->indcount
= 0x2 - calljmp_kludge
;
892 if ((eap
->base
= indregchk((reg_pt
) NOREG
)) != NOREG
)
894 if (eap
->indcount
== 0x0 && leading_displ
)
900 if ((eap
->index
= indregchk(eap
->base
)) != NOREG
)
904 if (eap
->indcount
== 0x0)
907 error(REPEATED_DISPL
);
908 expres(); /* this eats ADDOP, SUBOP, MULOP */
914 /* context-sensitive, STAR means scaled here*/
915 if (eap
->index
== NOREG
&& eap
->base
== ESPREG
)
917 error(INDEX_REG_EXP
);
923 if (!(lastexp
.data
& UNDBIT
) && lastexp
.offset
!= 0x1)
925 if (eap
->base
<= MAX16BITINDREG
||
926 (lastexp
.offset
!= 0x2 && lastexp
.offset
!= 0x4 &&
927 lastexp
.offset
!= 0x8))
931 eap
->scale
= lastexp
.offset
;
932 if (eap
->index
== NOREG
)
934 eap
->index
= eap
->base
;
939 lastexp
.data
= lastexp
.offset
= 0x0;
941 if ((sym
== ADDOP
|| sym
== SUBOP
))
943 if (eap
->indcount
== 0x0)
946 error(REPEATED_DISPL
);
953 error(REPEATED_DISPL
);
956 if (sym
!= rindirect
)
962 else if (!leading_immed
&& defsize
<= 0x2)
963 eap
->indcount
= 0x1; /* compatibility kludge */
965 eap
->displ
= lastexp
;
967 needcpu(eap
->size
==4?3:0);
970 PRIVATE
void getimmed(eap
, immed_count
)
978 eap
->size
= immed_count
;
979 buildimm(eap
, FALSE
);
983 PRIVATE
void getindirect(eap
)
984 register struct ea_s
*eap
;
987 if (eap
->indcount
== 0x0)
991 PRIVATE
void getshift(eap
)
992 register struct ea_s
*eap
;
996 if (eap
->base
!= CLREG
)
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
)
1011 if ((reg
= regchk()) != NOREG
)
1017 if (reg
!= DIREG
&& reg
!= SIREG
)
1020 error(INDEX_REG_EXP
);
1025 if (reg
!= BPREG
&& reg
!= BXREG
)
1028 error(INDEX_REG_EXP
);
1034 if (reg
<= MAX16BITINDREG
|| reg
== ESPREG
)
1037 error(INDEX_REG_EXP
);
1041 if (reg
> MAXINDREG
&& calljmp_kludge
== 0x0)
1043 if (matchreg
!= NOREG
)
1047 error(INDEX_REG_EXP
);
1053 PRIVATE
void kgerror(err_str
)
1057 sprefix
= oprefix
= aprefix
= mcount
= 0x0;
1060 PRIVATE
void lbranch(backamount
)
1063 mcount
+= defsize
+ 0x1;
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) */
1084 if (target
.indcount
>= 0x2 || target
.base
!= NOREG
)
1094 page
= PAGE1_OPCODE
;
1101 aprefix
= opcode
^ 0x1; /* kludged storage for short branch
1103 oprefix
= defsize
+ 0x1;
1105 opcode
= JMP_OPCODE
;
1114 PUBLIC
void mbswap()
1119 opcode
|= rm
[target
.base
];
1122 /* BR, CALL, J, JMP */
1128 register struct sym_s
*symptr
;
1131 if (sym
== IDENT
&& (symptr
= gsymptr
)->type
& MNREGBIT
&&
1132 symptr
->data
& SIZEBIT
)
1134 if(symptr
->value_reg_or_op
.op
.routine
== FAROP
)
1139 if(symptr
->value_reg_or_op
.op
.routine
== WORDOP
&&
1140 opcode
== JMP_SHORT_OPCODE
)
1142 opcode
= JMP_OPCODE
;
1148 if (asld_compatible
&& defsize
<= 0x2)
1150 calljmp_kludge
= 0x2;
1151 if (sym
== INDIRECT
)
1153 calljmp_kludge
= 0x0;
1159 if (indirect
&& target
.indcount
== 0x1)
1160 target
.indcount
= 0x2;
1161 calljmp_kludge
= 0x0;
1164 int tsize
= target
.size
?target
.size
:defsize
;
1165 if (opcode
== JMP_SHORT_OPCODE
)
1166 opcode
= JMP_OPCODE
;
1174 if (opcode
== JMP_OPCODE
)
1178 lastexp
= source
.displ
;
1179 if (!(lastexp
.data
& (FORBIT
| RELBIT
| UNDBIT
)) &&
1181 (offset_t
) (lastexp
.offset
+ 0x8000L
) >= 0x18000L
)
1185 buildimm(&target
, FALSE
);
1188 else if (target
.indcount
>= 0x2 || target
.base
!= NOREG
)
1191 notsegorspecreg(&target
);
1192 if (target
.indcount
== 0)
1193 notbytesize(&target
);
1196 if (opcode
== JMP_SHORT_OPCODE
)
1197 opcode
= JMP_OPCODE
;
1199 if (opcode
== JMP_OPCODE
)
1203 postb
|= opcode
+ far_diff
;
1207 else if (opcode
== JMP_SHORT_OPCODE
)
1210 ((pass
!=0 && !is8bitsignedoffset(lastexp
.offset
- lc
- 2)) ||
1213 opcode
= JMP_OPCODE
;
1218 lastexp
= target
.displ
;
1219 if (lastexp
.data
& IMPBIT
)
1222 lastexp
.data
= FORBIT
| UNDBIT
;
1228 lbranch(opcode
== JMP_OPCODE
? 0x83 : 0x0);
1233 PUBLIC
void mcalli()
1239 if (sym
== INDIRECT
)
1245 if (target
.indcount
>= 0x2 || target
.base
!= NOREG
)
1259 int tsize
= target
.size
?target
.size
:defsize
;
1265 lastexp
= target
.displ
;
1266 if (!(lastexp
.data
& (FORBIT
| RELBIT
| UNDBIT
)) &&
1268 (offset_t
) (lastexp
.offset
+ 0x8000L
) >= 0x18000L
)
1271 if( tsize
!= defsize
) oprefix
= 0x66;
1274 needcpu(tsize
==4?3:0);
1277 buildimm(&source
, FALSE
);
1282 /* DIV, IDIV, MUL */
1284 PUBLIC
void mdivmul()
1286 if (getaccumreg(&source
))
1292 buildunary(0xF6 | regsegword
[source
.base
]);
1300 PUBLIC
void menter()
1303 getimmed(&target
, 0x2);
1305 getimmed(&source
, 0x1);
1309 lastexp
= target
.displ
; /* getimmed(&source) wiped it out */
1314 /* arpl r/m16,r16 (Intel manual opcode chart wrongly says EwRw) */
1326 /* [cmpxchg xadd] [r/m8,r8 r/m16,r16, r/m32,r32] */
1339 PUBLIC
void mf_inher()
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 */
1353 getindirect(&source
);
1354 if (source
.size
!= 0x0)
1359 /* [fldcw fnstcw] mem2i */
1364 getindirect(&source
);
1365 if (source
.size
!= 0x0 && source
.size
!= 0x2)
1370 /* fnstsw [mem2i ax] */
1372 PUBLIC
void mf_m2_ax()
1374 if (getaccumreg(&target
))
1376 if (target
.base
!= AXREG
)
1381 target
.base
= ST0REG
; /* fake, really ax */
1389 /* [fiadd ficom ficomp fidiv fidivr fimul fist fisub fisubr] [mem2i mem4i] */
1391 PUBLIC
void mf_m2_m4()
1394 getindirect(&source
);
1395 if (source
.size
== 0x0)
1397 else if (source
.size
== 0x2)
1399 else if (source
.size
!= 0x4)
1404 /* [fild fistp] [mem2i mem4i mem8i] */
1406 PUBLIC
void mf_m2_m4_m8()
1409 getindirect(&source
);
1410 if (source
.size
== 0x0)
1412 else if (source
.size
== 0x2)
1414 else if (source
.size
== 0x8)
1415 opcode
|= 0x45; /* low bits 0 -> 5 and 3 -> 7 */
1416 else if (source
.size
!= 0x4)
1421 /* [fcom fcomp] [mem4r mem8r optional-st(i)] */
1423 PUBLIC
void mf_m4_m8_optst()
1427 target
.base
= ST1REG
;
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
)
1442 source
.base
= fpregchk();
1443 if (source
.base
== NOREG
)
1446 source
.base
= ST0REG
;
1448 if (target
.base
== ST0REG
)
1449 target
.base
= source
.base
;
1452 if (source
.base
!= ST0REG
)
1453 error(ILL_FP_REG_PAIR
);
1455 if ((opcode
& 0x07) >= 0x4)
1456 opcode
^= 0x01; /* weird swap of fdiv/fdivr, fsub/fsubr */
1463 getindirect(&source
);
1464 if (source
.size
== 0x0)
1466 else if (source
.size
== 0x8)
1468 else if (source
.size
!= 0x4)
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
)
1488 getindirect(&source
);
1489 if (source
.size
== 0x0)
1491 else if (source
.size
== 0x8)
1493 else if (source
.size
!= 0x4)
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
)
1513 getindirect(&source
);
1514 if (source
.size
== 0x0)
1516 else if (source
.size
== 0x8)
1518 else if (source
.size
== 0xA)
1519 opcode
|= 0x25; /* low bits 0 -> 5 and 3 -> 7 */
1520 else if (source
.size
!= 0x4)
1526 /* [fbld fbstp] mem10r */
1528 PUBLIC
void mf_m10()
1531 getindirect(&source
);
1532 if (source
.size
!= 0xA)
1541 target
.base
= fpregchk();
1542 if (target
.base
== NOREG
)
1543 kgerror(FP_REG_REQ
);
1547 /* [fucom fucomp fxch] optional-st(i) */
1549 PUBLIC
void mf_optst()
1553 target
.base
= ST1REG
;
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
);
1571 source
.base
= fpregchk();
1572 if (source
.base
== NOREG
)
1574 kgerror(FP_REG_REQ
);
1577 if (source
.base
!= ST0REG
)
1579 kgerror(ILL_FP_REG
);
1585 PUBLIC
void mf_w_inher()
1587 sprefix
= WAIT_OPCODE
;
1591 /* [fsave fstenv] mem */
1593 PUBLIC
void mf_w_m()
1595 sprefix
= WAIT_OPCODE
;
1601 PUBLIC
void mf_w_m2()
1603 sprefix
= WAIT_OPCODE
;
1607 /* fstsw [mem2i ax] */
1609 PUBLIC
void mf_w_m2_ax()
1611 sprefix
= WAIT_OPCODE
;
1615 /* ADC, ADD, AND, CMP, OR, SBB, SUB, XOR */
1617 PUBLIC
void mgroup1()
1620 notsegorspecreg(&source
);
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
);
1636 buildunary(0x80 | segword
);
1637 buildimm(&source
, TRUE
);
1642 opcode
|= direction
| segword
;
1648 /* RCL, RCR, ROL, ROR, SAL, SAR, SHL, SHR */
1650 PUBLIC
void mgroup2()
1654 buildsegword(&target
);
1658 buildunary(0xD0 | segword
);
1659 if (source
.base
== CLREG
)
1661 else if (source
.displ
.offset
!= 0x1)
1666 buildimm(&source
, FALSE
);
1671 /* LLDT, LTR, SLDT, STR, VERR, VERW */
1673 PUBLIC
void mgroup6()
1682 /* INVLPG, LGDT, LIDT, LMSW, SGDT, SIDT, SMSW */
1684 PUBLIC
void mgroup7()
1686 needcpu(2); /* I think INVLPG is actually 386 */
1688 if (opcode
== 0x20 || opcode
== 0x30)
1695 getindirect(&target
);
1697 if (target
.size
!= 0x0 && target
.size
!= 0x6)
1698 error(MISMATCHED_SIZE
); /* XXX - size 6 wrong for INVLPG? */
1703 /* BT, BTR, BTS, BTC */
1705 PUBLIC
void mgroup8()
1713 notindirect(&source
);
1714 notsegorspecreg(&source
);
1717 if (source
.base
== NOREG
)
1721 buildimm(&source
, TRUE
);
1732 /* BSF, BSR, LAR, LSL (Intel manual opcode chart wrongly says GvEw for L*) */
1745 /* bound [r16,m16&16 r32,m32&32] */
1752 getindirect(&target
);
1757 /* LDS, LES, LFS, LGS, LSS */
1764 getindirect(&target
);
1765 if (target
.size
!= 0x0 && target
.size
!= 0x2 + source
.size
)
1766 error(MISMATCHED_SIZE
);
1778 buildsegword(&target
);
1779 buildunary(0xF6 | segword
);
1783 notindirect(&target
);
1784 source
= target
; /* direction is swapped */
1786 notsegorspecreg(&target
);
1788 if (sym
!= COMMA
&& (target
.indcount
!= 0x0 || target
.base
!= NOREG
))
1791 page
= PAGE1_OPCODE
;
1809 source2
.size
= target
.size
;
1810 if (is8bitsignedoffset(source2
.displ
.offset
))
1817 source2
.size
= target
.size
;
1822 buildimm(&source2
, FALSE
);
1831 if (opcode
& WORDBIT
) /* inw; ind not supported */
1833 if (sym
== EOLSYM
&& mnsize
!= 0x0)
1834 target
.size
= mnsize
;
1837 if (getaccumreg(&target
))
1839 if (mnsize
!= 0x0 && regsize
[target
.base
] != mnsize
)
1840 error(MISMATCHED_SIZE
);
1844 target
.size
= regsize
[target
.base
= mnsize
< 0x2 ? ALREG
: AXREG
];
1845 opcode
|= regsegword
[target
.base
];
1846 if (!getdxreg(&source
))
1848 getimmed(&source
, 0x1);
1852 if (target
.size
> 0x1 && target
.size
!= defsize
)
1858 PUBLIC
void mincdec()
1862 buildsegword(&target
);
1863 if (target
.indcount
== 0x0 && segword
== WORDBIT
)
1864 opcode
|= 0x40 | rm
[target
.base
];
1866 buildunary(0xFE | segword
);
1869 /* CBW, CWD, CMPSW, INSW, IRET, LODSW, POPA, POPF, PUSHA, PUSHF */
1870 /* MOVSW, OUTSW, SCASW, STOSW */
1872 PUBLIC
void minher16()
1879 /* CWDE, CDQ, CMPSD, INSD, IRETD, LODSD, POPAD, POPFD, PUSHAD, PUSHFD */
1880 /* MOVSD, OUTSD, SCASD, STOSD */
1882 PUBLIC
void minher32()
1892 PUBLIC
void minhera()
1897 target
.displ
.offset
= 0xA;
1899 buildimm(&target
, FALSE
);
1902 getimmed(&target
, 0x1);
1910 getimmed(&target
, 0x1);
1911 if (!(immadr
.data
& (FORBIT
| RELBIT
| UNDBIT
)) &&
1912 (opcode_t
) immadr
.offset
== 0x3)
1923 /* First look for j* near */
1925 gsymptr
->type
& MNREGBIT
&&
1926 gsymptr
->data
& SIZEBIT
&&
1927 gsymptr
->value_reg_or_op
.op
.routine
== WORDOP
&&
1932 if (target
.indcount
>= 0x2 || target
.base
!= NOREG
)
1937 page
= PAGE1_OPCODE
;
1943 else if (!jumps_long
|| opcode
> 0x80) /* above 0x80 means loop, not long */
1948 lastexp
= target
.displ
;
1950 if ( (pass
!=0 && !is8bitsignedoffset(lastexp
.offset
- lc
- 2)) ||
1953 if (target
.indcount
>= 0x2 || target
.base
!= NOREG
)
1956 aprefix
= opcode
^ 0x1; /* kludged storage for short branch
1958 oprefix
= defsize
+ 0x1;
1960 opcode
= JMP_OPCODE
;
1967 if (lastexp
.data
& IMPBIT
)
1970 lastexp
.data
= FORBIT
| UNDBIT
;
1981 if (opcode
!= defsize
)
1984 ++mcount
; /* quick fix - mshort() needs to know */
1989 --mcount
; /* quick fix - main routine bumps it again */
1996 Gv(&source
); /* back to front */
1999 getindirect(&target
);
2009 if (segword
>= SEGMOV
)
2012 notimmed(&target
); /* target is actually the source */
2013 if (segword
> SEGMOV
) /* special reg */
2014 notindirect(&target
);
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
)
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
];
2036 opcode
= 0xC6 | segword
;
2038 buildimm(&source
, FALSE
);
2042 if (isspecreg(source
.base
))
2045 page
= PAGE1_OPCODE
;
2049 opcode
|= direction
| segword
;
2063 if (target
.size
== 0x0)
2065 if (target
.size
> 0x2)
2068 if (source
.size
!= defsize
)
2070 buildsegword(&target
);
2077 PUBLIC
void mnegnot()
2081 buildsegword(&target
);
2082 buildunary(0xF6 | segword
);
2090 if (opcode
& WORDBIT
) /* outw; outd not supported */
2092 if (sym
== EOLSYM
&& mnsize
!= 0x0)
2093 source
.size
= mnsize
;
2096 if (!getdxreg(&target
))
2098 getimmed(&target
, 0x1);
2104 if (!getaccumreg(&source
))
2105 kgerror(AL_AX_EAX_EXP
);
2106 else if (mnsize
!= 0x0 && regsize
[source
.base
] != mnsize
)
2107 error(MISMATCHED_SIZE
);
2110 source
.size
= regsize
[source
.base
= mnsize
< 0x2 ? ALREG
: AXREG
];
2111 opcode
|= regsegword
[source
.base
];
2113 if (source
.size
> 0x1 && source
.size
!= defsize
)
2119 PUBLIC
void mpushpop()
2125 buildsegword(&target
);
2126 notbytesize(&target
);
2127 if ((oldopcode
= opcode
) == POP_OPCODE
)
2130 if (target
.base
== CSREG
)
2131 kgerror(ILL_SEG_REG
);
2135 if (target
.indcount
== 0x0)
2137 if (segword
== SEGMOV
)
2139 switch (target
.base
)
2155 page
= PAGE1_OPCODE
;
2160 page
= PAGE1_OPCODE
;
2164 if (oldopcode
== POP_OPCODE
)
2167 else if (target
.base
!= NOREG
)
2169 opcode
= 0x50 | rm
[target
.base
];
2170 if (oldopcode
== POP_OPCODE
)
2176 if (oldopcode
== POP_OPCODE
)
2178 buildimm(&target
, TRUE
);
2184 if (oldopcode
== PUSH_OPCODE
)
2185 postb
|= 0x6 << REG_SHIFT
;
2198 getimmed(&target
, 0x2);
2202 /* SEG CS/DS/ES/FS/GS/SS */
2208 if (regsegword
[reg
= regchk()] != SEGMOV
)
2214 opcode
= (segoverride
- CSREG
)[reg
];
2220 PUBLIC
void msetcc()
2230 PUBLIC
void mshdouble()
2240 lastexp
= target
.displ
; /* getshift() wiped it out */
2243 if (source2
.base
== CLREG
)
2248 buildimm(&source2
, FALSE
);
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.
2263 notsegorspecreg(&source
);
2264 if (source
.base
== NOREG
)
2268 if (target
.indcount
== 0x0
2269 && (target
.base
== ALREG
|| target
.base
== AXREG
2270 || target
.base
== EAXREG
))
2271 opcode
= 0xA8 | segword
;
2275 opcode
= 0xF6 | segword
;
2278 buildimm(&source
, FALSE
);
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.
2298 notsegorspecreg(&source
);
2299 if (target
.indcount
== 0x0)
2301 if (target
.base
== AXREG
|| target
.base
== EAXREG
)
2303 opcode
= 0x90 + rm
[source
.base
];
2306 if (source
.base
== AXREG
|| source
.base
== EAXREG
)
2308 opcode
= 0x90 + rm
[target
.base
];
2316 PRIVATE
void notbytesize(eap
)
2317 register struct ea_s
*eap
;
2319 if (eap
->size
== 0x1)
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)
2337 PRIVATE
void notsegorspecreg(eap
)
2338 register struct ea_s
*eap
;
2340 if (regsegword
[eap
->base
] >= SEGMOV
)
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
)
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
);
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 */
2397 PRIVATE opcode_t tfrexg1
[] = /* transfer/exchange codes for source reg */
2411 PRIVATE opcode_t tfrexg2
[] = /* transfer/exchange codes for target reg */
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()
2439 if (postb
& INDIRECTBIT
)
2440 inderror(ILLMOD
); /* single-inc indirect illegal */
2443 lastexp
.offset
&= 0xFF00; /* for printing if postbyte is 0: ,X+ */
2447 else if (sym
== POSTINCOP
)
2457 /* common code for all-mode ops, alterable-mode ops, indexed ops */
2459 PRIVATE
void doaltind()
2462 if (sym
== LBRACKET
)
2464 postb
= INDIRECTBIT
;
2467 if (sym
!= RBRACKET
)
2474 PRIVATE
void do1altind()
2476 bool_t byteflag
; /* set if direct or short indexed adr forced */
2480 bool_t wordflag
; /* set if extended or long indexed adr forced*/
2482 if ((reg
= regchk()) != NOREG
)
2496 if (indreg(MAXINDREG
) != NOREG
)
2507 else if (sym
== SUBOP
) /* could be -R or - in expression */
2509 oldlineptr
= lineptr
; /* save state */
2510 oldsymname
= symname
;
2513 lineptr
= oldlineptr
;
2514 symname
= oldsymname
;
2517 predec1(); /* it's -R */
2522 else if (sym
== COMMA
)
2531 else if (sym
!= PREDECOP
)
2533 if (indreg(MAXINDREG
) != NOREG
)
2538 if (sym
== PREDECOP
)
2545 /* should have expression */
2547 wordflag
= byteflag
= FALSE
;
2548 if (sym
== LESSTHAN
)
2550 /* context-sensitive, LESSTHAN means byte-sized here */
2554 else if (sym
== GREATERTHAN
)
2556 /* context-sensitive, GREATERTHAN means word-sized here */
2562 { /* offset from register */
2564 if ((reg
= indreg(PCREG
)) == NOREG
)
2566 postb
|= 0x8; /* default 8 bit offset */
2570 if (!(lastexp
.data
& (RELBIT
| UNDBIT
)))
2572 lastexp
.offset
= lastexp
.offset
- lc
;
2574 lastexp
.offset
-= 0x4; /* extra for instruction */
2576 lastexp
.offset
-= 0x3; /* 3 byte instruction
2577 assuming 8 bit offset */
2582 if (!(lastexp
.data
& (RELBIT
| UNDBIT
)) &&
2583 !is8bitsignedoffset(lastexp
.offset
))
2584 error(ABOUNDS
); /* forced short form is impossible */
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
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 */
2604 postb
|= (lastexp
.offset
& 0x1F);
2606 else /* 8 bit offset */
2610 else if (postb
& INDIRECTBIT
)
2611 { /* extended indirect */
2616 else if (postb
& INDEXBIT
)
2617 inderror(ILLMOD
); /* e.g. LEAX $10 */
2620 if (byteflag
|| (!wordflag
&& !(lastexp
.data
& (FORBIT
| RELBIT
)) &&
2621 (lastexp
.offset
>> 0x8) == dirpag
))
2622 { /* direct addressing */
2626 else /* extended addressing */
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 */
2642 PRIVATE
void fixupind()
2644 if ((opcode
& 0x30) == 0x0) /* change all but LEA opcodes */
2653 PRIVATE
void getindexnopost()
2656 if (indreg(MAXINDREG
) != NOREG
)
2660 PRIVATE
void inderror(err_str
)
2664 if (postb
& INDIRECTBIT
)
2665 sym
= RBRACKET
; /* fake right bracket to kill further errors */
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
)
2678 if ((reg
= regchk()) == NOREG
)
2680 else if (reg
> maxindex
)
2687 postb
|= rrindex
[reg
];
2697 if (sym
== IMMEDIATE
)
2703 /* alterable mode ops */
2705 PUBLIC
void malter()
2707 postb
= 0x0; /* not yet indexed or indirect */
2711 /* indexed mode ops */
2713 PUBLIC
void mindex()
2715 postb
= INDEXBIT
; /* indexed but not yet indirect */
2721 PUBLIC
void mimmed()
2726 if (sym
!= IMMEDIATE
)
2730 if (opcode
>= 0x80 && ((nybble
= opcode
& 0xF) == 0x3 ||
2731 nybble
== 0xC || nybble
>= 0xE))
2732 ++mcount
; /* magic for long immediate */
2734 if (pass2
&& mcount
<= 0x2)
2746 mcount
+= 0x3; /* may be 0x0 or 0x1 here */
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 */
2764 PUBLIC
void msstak()
2776 if ((reg
= regchk()) == NOREG
)
2780 postb
= tfrexg1
[reg
];
2787 if ((reg
= regchk()) == NOREG
)
2789 else if ((postb
|= tfrexg2
[reg
])
2790 & 0x88 && (postb
& 0x88) != 0x88)
2791 error(ILLREG
); /* registers not of same size */
2798 PUBLIC
void mustak()
2803 PRIVATE
void predec1()
2805 if (postb
& INDIRECTBIT
)
2806 inderror(ILLMOD
); /* single-dec indirect illegal */
2814 /* common routine for PSHS/PULS/PSHU/PULU */
2816 PRIVATE
void sustack(stackreg
)
2822 while ((reg
= regchk()) != NOREG
)
2824 if (reg
== stackreg
)
2826 error(ILLREG
); /* cannot stack self */
2829 postb
|= pushpull
[reg
];
2839 /* routines common to all processors */
2841 PUBLIC
void getcomma()
2852 /* AAA, AAS, CLC, CLD, CLI, CLTS, CMC, CMPSB, DAA, DAS, HLT, INTO, INSB, */
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()
2862 /* short branches */
2864 PUBLIC
void mshort()
2870 PRIVATE
void mshort2()
2876 if (lastexp
.data
& RELBIT
)
2878 else if (!(lastexp
.data
& UNDBIT
))
2880 lastexp
.offset
= lastexp
.offset
- lc
- mcount
;
2881 if (!is8bitsignedoffset(lastexp
.offset
))
2887 /* check if current symbol is a register, return register number or NOREG */
2889 PRIVATE reg_pt
regchk()
2891 register struct sym_s
*symptr
;
2895 if ((symptr
= gsymptr
)->type
& MNREGBIT
)
2897 if (symptr
->data
& REGBIT
)
2899 int regno
= symptr
->value_reg_or_op
.reg
;
2901 if (regno
== ST0REG
&& !fpreg_allowed
)
2902 error(FP_REG_NOT_ALLOWED
);
2905 needcpu((regno
==FSREG
||regno
==GSREG
)?3:0);
2906 needcpu((regno
>=EAXREG
&& regno
<=ESPREG
)?3:0);
2907 needcpu((regno
>=CR0REG
&& regno
<=TR7REG
)?3:0);
2913 if( last_pass
== 1 )
2914 if (!(symptr
->type
& (LABIT
| MACBIT
| VARBIT
)))
2915 symptr
->data
|= FORBIT
; /* show seen in advance */
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 */
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
);