summaryrefslogtreecommitdiffstats
path: root/private/sdktools/masm/asmopcod.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/sdktools/masm/asmopcod.c')
-rw-r--r--private/sdktools/masm/asmopcod.c567
1 files changed, 567 insertions, 0 deletions
diff --git a/private/sdktools/masm/asmopcod.c b/private/sdktools/masm/asmopcod.c
new file mode 100644
index 000000000..ce556f1d4
--- /dev/null
+++ b/private/sdktools/masm/asmopcod.c
@@ -0,0 +1,567 @@
+/* asmopcod.c -- microsoft 80x86 assembler
+**
+** microsoft (r) macro assembler
+** copyright (c) microsoft corp 1986. all rights reserved
+**
+** randy nevin
+**
+** 10/90 - Quick conversion to 32 bit by Jeff Spencer
+*/
+
+#include <stdio.h>
+#include "asm86.h"
+#include "asmfcn.h"
+
+
+#ifdef FIXCOMPILERBUG
+//BUGBUG foobarfoofoo simply takes up space to get around a compiler bug
+foobarfoofoo()
+{
+ int foo;
+
+ for( foo = 0; foo < 100000; foo++ );
+ for( foo = 0; foo < 100000; foo++ );
+ for( foo = 0; foo < 100000; foo++ );
+ for( foo = 0; foo < 100000; foo++ );
+ for( foo = 0; foo < 100000; foo++ );
+ for( foo = 0; foo < 100000; foo++ );
+}
+#endif
+
+/*** forcesize - check for no size in pass 2
+ *
+ * routine ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+forcesize (
+ DSCREC *arg
+){
+ register struct psop *pso; /* parse stack operand structure */
+
+ pso = &(arg->dsckind.opnd);
+ if (pass2)
+ if (!pso->sized)
+ errorc (E_OHS);
+ else if (M_CODE & pso->dtype)
+ /* Not data assoc */
+ errorc (E_ASD);
+
+ if (arg != fltdsc) /* Large size ok for 8087 */
+
+ if (pso->dsize > 2 && (
+#ifdef V386
+ !(cputype&P386) ||
+#endif
+ pso->dsize != 4))
+ /* Illegal item size */
+ errorc (E_IIS);
+}
+
+
+
+
+/*** checkmatch - check memory and register
+ *
+ * checkmatch ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ * Note Give error if Dmem has a size and does not match Dreg.
+ * Force to same size
+ */
+
+
+VOID PASCAL CODESIZE
+checkmatch (
+ DSCREC *dreg,
+ DSCREC *dmem
+){
+ register struct psop *psor; /* parse stack operand structure */
+ register struct psop *psom; /* parse stack operand structure */
+
+ psor = &(dreg->dsckind.opnd);
+ psom = &(dmem->dsckind.opnd);
+ if (psom->sized && (psom->w != psor->w
+
+#ifdef V386
+ || (psom->dsize && psor->dsize != psom->dsize)
+#endif
+ ))
+ errorc ((USHORT)(psom->mode == psor->mode? E_OMM & ~E_WARN1: E_OMM));
+
+ psom->w = psor->w;
+}
+
+
+
+
+/*** emitopcode - emit opcode to linker and display on listing
+ *
+ * emitopcode (val);
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+emitopcode (
+ UCHAR v
+){
+ if (pass2 || debug) {
+ if (pass2 && emittext)
+ /* Output to linker */
+ emitcbyte (v);
+ /* Display on listing */
+ opdisplay (v);
+ }
+ if (emittext)
+ pcoffset++;
+}
+
+
+
+
+/*** emitmodrm - emit modrm byte 64*p1+8*p2+p3
+ *
+ * emitmodrm (p1, p2, p3);
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+emitmodrm (
+ USHORT p1,
+ USHORT p2,
+ USHORT p3
+){
+
+#ifdef V386
+ if (p1>7)
+ {
+ /* 386 SIB opcodes have wired in RM of ESP */
+ emitopcode ((UCHAR)(((p1-8) << 6) + (p2 << 3) + 4));
+ listindex--;
+ emitopcode ((UCHAR)p3);
+ }
+ else
+#endif
+ emitopcode ((UCHAR)(((p1 > 3 ? (p1-5) : p1) << 6) + (p2 << 3) + p3));
+}
+
+
+
+
+/*** emitescape - emit segment escapt byte
+ *
+ * emitescape ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+emitescape (
+ DSCREC *dsc,
+ UCHAR sreg
+){
+ register struct psop *pso; /* parse stack operand structure */
+
+ pso = &(dsc->dsckind.opnd);
+ if (pso->seg < NOSEG && pso->seg != sreg && pso->mode != 4) {
+ if (checkpure && (cputype & (P286|P386)) && pso->seg == CSSEG)
+ impure = TRUE;
+
+ if (pso->seg < FSSEG)
+ emitopcode((UCHAR)(0x26|(pso->seg<<3)));
+#ifdef V386
+ else if (cputype & P386)
+ emitopcode((UCHAR)(0x60|pso->seg));
+#endif
+ else
+ errorc (E_CRS);
+ /* Flag is prefix */
+ listbuffer[listindex-1] = ':';
+ listindex++;
+ }
+ if (pso->seg > NOSEG)
+ /* Unknown segreg */
+ errorc (E_CRS);
+}
+
+#ifdef V386
+
+VOID PASCAL CODESIZE
+emitsize (
+ USHORT value
+){
+ if (! (cputype & P386)) {
+
+ if (errorcode == (E_IIS&~E_WARN1))
+ errorcode = 0;
+
+ errorc(E_IIS&~E_WARN1);
+ }
+
+ emitopcode((UCHAR)value);
+ listbuffer[listindex-1] = '|';
+ listindex++;
+}
+
+#endif
+
+
+
+
+
+/*** byteimmcheck - check if value is -128 .. +127
+ *
+ * routine ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+byteimmcheck (
+ register struct psop *pso
+){
+ register USHORT t;
+
+ t = pso->doffset;
+ if (pso->dsign)
+ t = -t;
+
+ if (t > (USHORT) 0x7F && t < (USHORT)~0x7F)
+ errorc (E_VOR);
+}
+
+
+/*** emitOP - emit operand, value which may be in segment
+ *
+ * routine ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+emitOP (
+ register struct psop *pso
+){
+ USHORT i, fSegOnly;
+
+ if (pso->dsign)
+ pso->doffset = -pso->doffset;
+
+ pso->dsign = FALSE;
+
+ if (fNeedList) {
+
+ fSegOnly = (pso->fixtype == FBASESEG || pso->fixtype == FGROUPSEG);
+
+ if (pso->dflag == INDETER) { /* Have ? */
+
+ for (i = 1; i <= 2 * pso->dsize; i++) {
+ listbuffer[listindex] = '?';
+ if (listindex < LSTMAX)
+ listindex++;
+ else
+ resetobjidx ();
+ }
+ }
+ else if (pso->dsize == 1) {
+
+ opdisplay ((UCHAR) pso->doffset);
+ listindex--;
+ }
+ else if (!fSegOnly) {
+
+ if (pso->dsize > 4 ||
+ pso->dsize == 4 &&
+ ((pso->fixtype&7) == FOFFSET || pso->fixtype == FCONSTANT)) {
+
+ /* list full 32 bits, even if top is 0 */
+
+ if (!highWord(pso->doffset)){
+ offsetAscii((OFFSET) 0);
+ copyascii();
+ }
+ offsetAscii (pso->doffset);
+ }
+ else
+ offsetAscii (pso->doffset & 0xffff);
+
+ copyascii ();
+ }
+
+ if ((pso->fixtype&7) == FPOINTER || fSegOnly) {
+
+ if (pso->dsize != 2)
+ listindex++;
+
+ copytext ("--");
+ copytext ("--");
+ }
+ if (pso->dflag == XTERNAL)
+ copytext (" E");
+ else if (pso->dsegment)
+ copytext (" R");
+ if (pso->dflag == UNDEFINED)
+ copytext (" U");
+
+ listindex++;
+
+ if (fSegOnly && pso->dsize == 4){
+ copytext("00");
+ copytext("00");
+ }
+
+ }
+ if (emittext) {
+ if (pass2)
+ if (pso->dflag != UNDEFINED)
+ emitobject (pso);
+
+ else if (pso->dsize != 1)
+ emitcword ((OFFSET) 0); /* Just put out word */
+
+ else {
+ if (((USHORT) (pso->doffset >> 8)) != (USHORT)0 &&
+ ((USHORT) (pso->doffset >> 8)) != (USHORT)-1)
+
+ errorc (E_VOR);
+
+ emitcbyte (0);
+ }
+
+ pcoffset += pso->dsize;
+ }
+}
+
+
+
+
+/*** emitrest - emit displacement or immediate values based on
+ * address passed in address mode
+ *
+ * emitrest (opc);
+ *
+ * Entry *opc = parse stack entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+emitrest (
+ DSCREC *opc
+){
+ register struct psop *pso; /* parse stack operand structure */
+
+ pso = &(opc->dsckind.opnd);
+
+ if ((pso->mode != 3 && pso->mode != 4) && (pso->fixtype == FNONE))
+ pso->fixtype = FCONSTANT;
+
+ switch(pso->mode)
+ /* There is something to output */
+ {
+ case 0:
+ if(pso->rm != 6) break;
+ case 2:
+ pso->dsize = 2;
+ goto bpcomm;
+
+ /* 386 modes, 4 byte displacements */
+ case 5:
+ case 8:
+ if ((pso->rm&7) != 5) break;
+ case 7:
+ case 10:
+ pso->dsize = 4;
+ bpcomm:
+ /* we get empty dsize from some callers. for this operand,
+ * we need to make it an offset. but not for far calls and
+ * jumps */
+
+ if ((pso->fixtype&7) == FPOINTER)
+ pso->dsize += 2;
+
+ emitOP (pso);
+ break;
+ case 1:
+ case 6:
+ case 9:
+ pso->dsize = 1;
+ emitOP (pso);
+ break;
+ case 3:
+ break;
+ case 4:
+ /* Immediate mode */
+ if (!pso->w || pso->dsize == 0)
+ pso->dsize = (pso->w ? wordsize : 1);
+
+ emitOP (pso);
+ }
+}
+
+
+
+
+/*** errorforward - generate error if forward reference on pass 2
+ *
+ * routine ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+errorforward (
+ DSCREC *arg
+){
+ if (pass2)
+ if (arg->dsckind.opnd.dflag == FORREF)
+ errorc (E_IFR);
+}
+
+
+
+
+/*** errorimmed - generate error if immediate operand
+ *
+ * routine ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+errorimmed (
+ DSCREC *dsc
+){
+ if (dsc->dsckind.opnd.mode == 4) {
+ errorc (E_NIM);
+ dsc->dsckind.opnd.mode = 2;
+ }
+}
+
+
+
+
+/*** rangecheck - check for register number within range
+ *
+ * routine ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+rangecheck (
+ USHORT *v,
+ UCHAR limit
+){
+ if (*v > limit) {
+ if (limit <= 7)
+ errorc (E_IRV);
+ else
+ errorc (E_VOR);
+ *v = limit;
+ }
+}
+
+VOID PASCAL CODESIZE
+valuecheck(
+ OFFSET *v,
+ USHORT limit
+){
+ if (*v > limit) {
+ if (limit <= 7)
+ errorc (E_IRV);
+ else
+ errorc (E_VOR);
+ *v = limit;
+ }
+}
+
+
+
+
+/*** forceaccum - generate error if not register AX or AL
+ *
+ * routine ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+forceaccum (
+ DSCREC *dsc
+){
+ if (dsc->dsckind.opnd.mode != 3 || dsc->dsckind.opnd.rm)
+ errorc (E_AXL);
+}
+
+
+
+
+/*** errorsegreg - generate error if operand is segment register
+ *
+ * errorsegreg (arg);
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+errorsegreg (
+ DSCREC *arg
+){
+ if (1 << REGRESULT & arg->dsckind.opnd.dtype)
+ if (arg->dsckind.opnd.dsegment->symu.regsym.regtype == SEGREG)
+ errorc (E_ISR);
+}