summaryrefslogtreecommitdiff
path: root/as
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1996-12-01 16:58:31 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:34:16 +0200
commitf8de35da65c5d93bb733073cf40da154bc1c0748 (patch)
treed28c7644739a24402376d24cb0020ea410a9ccff /as
parentc218c617b5be443b7968308506969ad2b726d73c (diff)
downloaddev86-f8de35da65c5d93bb733073cf40da154bc1c0748.tar.gz
Import Dev86src-0.0.9.tar.gzv0.0.9
Diffstat (limited to 'as')
-rw-r--r--as/Makefile12
-rw-r--r--as/TODO2
-rw-r--r--as/as.c23
-rw-r--r--as/as86_encap11
-rw-r--r--as/as86_to_data93
-rw-r--r--as/assemble.c39
-rw-r--r--as/const.h6
-rw-r--r--as/error.c2
-rw-r--r--as/express.c8
-rw-r--r--as/genlist.c6
-rw-r--r--as/globvar.h22
-rw-r--r--as/macro.c2
-rw-r--r--as/mops.c77
-rw-r--r--as/pops.c37
-rw-r--r--as/readsrc.c33
15 files changed, 323 insertions, 50 deletions
diff --git a/as/Makefile b/as/Makefile
index 736d144..3fb2551 100644
--- a/as/Makefile
+++ b/as/Makefile
@@ -2,12 +2,13 @@
ifneq ($(TOPDIR),)
include $(TOPDIR)/Make.defs
else
-CC=bcc
-LDFLAGS=-s
+CFLAGS=-O
+LIBDIR=/usr/bin
+BINDIR=/usr/bin
endif
# Temp needed for libc-5.4.7
-CFLAGS+=-Dwarn=as_warn
+CFLAGS+= -Dwarn=as_warn
OBJS =as.o assemble.o error.o express.o \
genbin.o genlist.o genobj.o gensym.o \
@@ -27,11 +28,6 @@ install: all
install -m 755 tmp $(BINDIR)/as86_encap
-@rm -f tmp
-# typeconv.o: dummy
-# -cp -p ../ld/typeconv.o .
-
-dummy:
-
clean:
rm -f *.o as86
diff --git a/as/TODO b/as/TODO
index 529aa7c..c7ff1e1 100644
--- a/as/TODO
+++ b/as/TODO
@@ -8,6 +8,4 @@ Accept gas format.
Decide how to choose between 8-bit and 32-bit branches. 16-bit branches in
32-bit mode are unusable because top 16 bits of PC are messed up.
-Limit insns to specified processor (warn for 386 insns on 8086).
-
Buffer for printing of listing.
diff --git a/as/as.c b/as/as.c
index f9965e8..ce72c13 100644
--- a/as/as.c
+++ b/as/as.c
@@ -42,7 +42,7 @@ char **argv;
{
#ifdef __AS386_16__
heapptr = sbrk(0);
- heapend = ((char*)&argc) - STAKSIZ;
+ heapend = ((char*)&argc) - STAKSIZ - 16;
brk(heapend);
if(sbrk(0) != heapend)
as_abort("Cannot allocate memory");
@@ -64,6 +64,7 @@ char **argv;
initsource(); /* only nec to init for unsupported mem file */
typeconv_init(BIG_ENDIAN, LONG_BIG_ENDIAN);
warn.global = TRUE; /* constant */
+ last_pass=1;
process_args(argc, argv);
initscan();
@@ -118,6 +119,7 @@ PUBLIC void initp1p2()
{
register struct lc_s *lcp;
+ dirty_pass = 0;
ifflag = TRUE;
pedata = UNDBIT; /* program entry point not defined */
blockstak = hid_blockstak + MAXBLOCK;
@@ -155,6 +157,11 @@ char **argv;
char *arg;
bool_t isnextarg;
char *nextarg = 0;
+ int opened_file = 0;
+
+#ifdef I80386
+ setcpu(0xF);
+#endif
if (argc <= 1)
usage();
@@ -175,11 +182,13 @@ char **argv;
switch (arg[1])
{
#ifdef I80386
- case '0':
+ case '0': case '1': case '2':
idefsize = defsize = 0x2;
+ setcpu(arg[1]-'0');
break;
case '3':
idefsize = defsize = 0x4;
+ setcpu(0xF);
break;
case 'a':
asld_compatible = TRUE;
@@ -199,6 +208,7 @@ char **argv;
#ifdef I80386
case 'j':
jumps_long = TRUE;
+ ++last_pass;
break;
#endif
case 'l':
@@ -257,9 +267,18 @@ char **argv;
as_abort("source file name too long");
infiln = infil0 = 1;
infil = open_input(strcpy(filnamptr, arg));
+ opened_file = 1;
}
}
while (--argc != 1);
+ if( !opened_file )
+ {
+ infiln = infil0 = 1;
+ infil = open_input(strcpy(filnamptr, "-"));
+ }
+#ifdef I80386
+ origcpuid = cpuid;
+#endif
inidata = (~binaryg & inidata) | (RELBIT | UNDBIT);
} /* IMPBIT from inidata unless binaryg */
diff --git a/as/as86_encap b/as/as86_encap
index 8e5d4ab..4d50e23 100644
--- a/as/as86_encap
+++ b/as/as86_encap
@@ -19,6 +19,7 @@
trap "rm -f _$$.* ; exit 99" 1 2 3 15
LIBDIR='%%LIBDIR%%' # Set by make install
+[ -d "$LIBDIR" ] || LIBDIR=/usr/bin
IFILE="$1"
OFILE="$2"
@@ -39,7 +40,7 @@ $LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
[ "$RV" = 0 ] && {
(
- cat _$$.sym
+ sort _$$.sym
echo %%%%
od -v -t uC _$$.bin
) | \
@@ -75,7 +76,13 @@ $LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
flg==1 {
if(NF == 0) next;
printf " ";
- for(i=2;i<=NF;i++) { printf("%3d,", $i); bincount++; }
+ for(i=2;i<=NF;i++) {
+ if( $i >= 32 && $i <= 127 && $i != 39 && $i != 92 )
+ printf("\047%c\047,", $i);
+ else
+ printf("%3d,", $i);
+ bincount++;
+ }
printf "\n";
}
END {
diff --git a/as/as86_to_data b/as/as86_to_data
new file mode 100644
index 0000000..ded1f0e
--- /dev/null
+++ b/as/as86_to_data
@@ -0,0 +1,93 @@
+#!/bin/sh -
+#
+# This file is simply an example of what can be done using the new binary
+# and symbol table output functions. It produces a byte array with the
+# symbols in the object as array references within it.
+#
+# The output is a Linux OMAGIC binary created by ld86 -N, this means the
+# object can be linked directly to C-functions created by the same GCC that
+# compiled ld86.
+#
+# Use it in a makefile:
+#
+# .s86.o:
+# as86_to_data $*.s86 $*.o $(AS86FLAGS)
+#
+
+[ $# -lt 2 ] && {
+ echo "Usage: `basename $0` infile outfile [as86 opts]" 1>&2
+ exit 1
+}
+
+trap "rm -f _$$.* ; exit 99" 1 2 3 15
+
+LIBDIR='%%LIBDIR%%' # Set by make install
+[ -d "$LIBDIR" ] || LIBDIR=/usr/bin
+
+IFILE="$1"
+OFILE="$2"
+
+shift ; shift
+RV=0
+
+$LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
+
+[ "$RV" = 0 ] && {
+ (
+ cat _$$.sym
+ echo %%%%
+ od -v -t uC _$$.bin
+ echo %%%%
+ ) | \
+ awk > _$$.v ' BEGIN{
+ startaddr="";
+ printf ".text\n.data\n";
+ }
+ /^%%%%$/ { flg++;
+ next;
+ }
+ flg==0 {
+ if(NF == 0) next;
+ if( substr($2,1,4) == "0000" ) $2=substr($2,5);
+ if( $1 == "+" && $4 == "$start" )
+ {
+ if( $2 != "0000" ) startaddr=" - $" $2;
+ }
+ else if( substr($3, 1, 1) == "E" && $4 != "start" && $4 != "size" && $4 != "data" )
+ {
+ printf "export _%s\n", $4
+ printf "_%s = * + $%s%s\n\n", $4, $2, startaddr;
+ }
+ next;
+ }
+ flg==1 {
+ if(NF <= 1) next;
+ printf " .byte ";
+ for(i=2;i<NF;i++) printf("%3d,", $i);
+ printf("%3d", $NF);
+ printf "\n";
+ }
+ '
+ RV=$?
+}
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+# If you want to see the assembler.
+# cp _$$.v `basename $2 .o`.asm
+
+$LIBDIR/as86 -o _$$.o86 _$$.v || RV=$?
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+$LIBDIR/ld86 -r -N _$$.o86 -o _$$.o || RV=$?
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+if [ "X$OFILE" = "X-" ]
+then cat _$$.o
+else mv -f _$$.o "$OFILE" || RV=$?
+fi
+
+rm -f _$$.*
+exit $RV
diff --git a/as/assemble.c b/as/assemble.c
index 1992068..c631905 100644
--- a/as/assemble.c
+++ b/as/assemble.c
@@ -9,6 +9,7 @@
#include "scan.h"
PRIVATE bool_t nocolonlabel; /* set for labels not followed by ':' */
+PRIVATE offset_t oldlabel = 0;
PRIVATE void (*routine) P((void));
PRIVATE pfv rout_table[] =
{
@@ -163,6 +164,13 @@ PUBLIC void assemble()
if (nocolonlabel)
error(NEEDENDLABEL);
#endif
+ if( label->value_reg_or_op.value != oldlabel)
+ {
+ dirty_pass = TRUE;
+ if( pass == last_pass )
+ error(UNSTABLE_LABEL);
+ }
+
label->type |= LABIT; /* confirm, perhaps redundant */
if (label->type & REDBIT)
{
@@ -203,6 +211,7 @@ PRIVATE void asline()
fqflag =
#endif
fdflag = fcflag = FALSE;
+ cpuwarn();
readline();
getsym();
if (sym != IDENT) /* expect label, mnemonic or macro */
@@ -219,6 +228,8 @@ PRIVATE void asline()
else if (!(symptr->type & (MACBIT | MNREGBIT)))
/* not macro, op, pseudo-op or register, expect label */
{
+ oldlabel = symptr->value_reg_or_op.value;
+
if ((nocolonlabel = (*lineptr - ':')) == 0) /* exported label? */
{
sym = COLON;
@@ -229,6 +240,26 @@ PRIVATE void asline()
if (symptr->type & REDBIT)
labelerror(RELAB);
label = symptr;
+
+#if 0
+if(pass==last_pass)
+{
+ if( ((label->data^lcdata)&~FORBIT) || label->value_reg_or_op.value != lc)
+ {
+ printf("Movement %x:%d -> %x:%d\n",
+ label->data,
+ label->value_reg_or_op.value,
+ lcdata,
+ lc);
+ }
+}
+#endif
+ /* This is a bit dodgy, I think it's ok but ... */
+ if (pass && (label->data & RELBIT))
+ {
+ label->data = (label->data & FORBIT) | lcdata;
+ label->value_reg_or_op.value = lc;
+ }
}
else if (checksegrel(symptr))
{
@@ -239,12 +270,13 @@ PRIVATE void asline()
symptr->type |= EXPBIT;
#endif
#endif
- symptr->data = (symptr->data & FORBIT) | lcdata;
/* remember if forward referenced */
+ symptr->data = (symptr->data & FORBIT) | lcdata;
symptr->value_reg_or_op.value = lc;
/* unless changed by EQU,COMM or SET */
label = symptr;
}
+
getsym();
if (sym != IDENT)
{
@@ -294,12 +326,17 @@ PRIVATE void asline()
}
}
opcode = symptr->value_reg_or_op.op.opcode;
+#ifdef I80386
+ needcpu((page==0 && ((opcode&0xF0) == 0x60||(opcode&0xF6)==0xC0))?1:0);
+#endif
routine = rout_table[symptr->value_reg_or_op.op.routine];
getsym();
(*routine)();
if (sym != EOLSYM)
error(JUNK_AFTER_OPERANDS);
#ifdef I80386
+ needcpu(page==PAGE1_OPCODE?2:0);
+
if (aprefix != 0)
++mcount;
if (oprefix != 0)
diff --git a/as/const.h b/as/const.h
index d5ed1ee..2265795 100644
--- a/as/const.h
+++ b/as/const.h
@@ -45,7 +45,7 @@
#ifdef __AS386_16__
# undef INBUFSIZE
# define INBUFSIZE 512
-# define STAKSIZ 256 /* table grows up to stack less this */
+# define STAKSIZ 512 /* table grows up to stack less this */
#endif
/* booleans */
@@ -325,9 +325,11 @@ enum
JUNK_AFTER_OPERANDS,
ALREADY,
+ UNSTABLE_LABEL,
/* Warnings. */
-#define MINWARN SHORTB
+#define MINWARN CPUCLASH
+ CPUCLASH,
SHORTB
};
diff --git a/as/error.c b/as/error.c
index 465ea31..683177f 100644
--- a/as/error.c
+++ b/as/error.c
@@ -84,6 +84,8 @@ PRIVATE char *errormessage[] =
"illegal FP register pair",
"junk after operands",
"already defined",
+ "label moved in last pass, add -j?",
+ "instruction illegal for current cpu",
"short branch would do",
"unknown error",
};
diff --git a/as/express.c b/as/express.c
index 70f5081..3e93061 100644
--- a/as/express.c
+++ b/as/express.c
@@ -27,7 +27,7 @@ PUBLIC void chkabs()
{
if (lastexp.data & RELBIT)
{
- if (pass != 0)
+ if (pass == last_pass)
error(ABSREQ);
expundefined();
}
@@ -56,7 +56,7 @@ PUBLIC void nonimpexpres()
PUBLIC void showrelbad()
{
- if (pass != 0)
+ if (pass == last_pass)
error(RELBAD);
expundefined();
}
@@ -281,7 +281,7 @@ PUBLIC void factor()
symptr->data |= FORBIT;
lastexp.sym = symptr;
}
- if (pass == 0)
+ if (pass != last_pass)
{
lastexp.data = symptr->data &
(FORBIT | RELBIT | UNDBIT | SEGM);
@@ -333,7 +333,7 @@ PUBLIC void factor()
case STAR:
/* context-sensitive, STAR means location counter here */
lastexp.offset = lc;
- if ((lastexp.data = lcdata) & UNDBIT && pass != 0)
+ if ((lastexp.data = lcdata) & UNDBIT && pass == last_pass)
experror(UNBLAB);
getsym();
return;
diff --git a/as/genlist.c b/as/genlist.c
index 37d2caf..e1c43ea 100644
--- a/as/genlist.c
+++ b/as/genlist.c
@@ -349,7 +349,7 @@ PRIVATE void listerrors()
do
{
#ifdef I80386
- if(column)
+ if(errcol != CODE_LIST_LENGTH)
{
writenl(); paderrorline(1);
}
@@ -363,7 +363,7 @@ PRIVATE void listerrors()
++errcol;
}
#endif
- while (column < errptr->position)
+ while (errptr && errptr->position < 132 && column < errptr->position)
{
++column;
if (*linep++ == '\t') /* next tab (standard tabs only) */
@@ -381,7 +381,7 @@ PRIVATE void listerrors()
}
}
#ifdef I80386
- writec('^');
+ writec('^'); ++errcol;
#else
if (errcolw < errcol) /* position under error on new line */
{
diff --git a/as/globvar.h b/as/globvar.h
index e44d88d..aed6aed 100644
--- a/as/globvar.h
+++ b/as/globvar.h
@@ -80,6 +80,8 @@ EXTERN opcode_t page;
EXTERN opcode_t opcode;
EXTERN opcode_t postb; /* postbyte, 0 if none */
EXTERN unsigned char pcrflag; /* OBJ_RMASK set if addressing is PC-relative */
+EXTERN int last_pass; /* Pass number of last pass */
+EXTERN int dirty_pass; /* Set if this pass had a label movement */
#ifdef I80386
@@ -91,8 +93,28 @@ EXTERN opcode_t oprefix; /* operand size prefix or 0 */
EXTERN opcode_t sprefix; /* segment prefix or 0 */
EXTERN opcode_t sib; /* scale-index-base byte */
+EXTERN int cpuid; /* Assembler instruction limit flag */
+EXTERN int origcpuid; /* Assembler instruction limit flag */
+
#endif
/* miscellaneous */
extern char hexdigit[];
+
+/* cpuid functions */
+#ifdef I80386
+#ifndef __AS386_16__
+#define iscpu(x) (cpuid>=(x))
+#define needcpu(x) do{ if(cpuid<(x)) {error(CPUCLASH); cpuid|=0x10;} }while(0)
+#define setcpu(x) (cpuid=(x))
+#define cpuwarn() (cpuid&=0xF)
+#endif
+#endif
+
+#ifndef setcpu
+#define needcpu(x)
+#define setcpu(x)
+#define cpuwarn()
+#endif
+
diff --git a/as/macro.c b/as/macro.c
index f0fc758..e6c1173 100644
--- a/as/macro.c
+++ b/as/macro.c
@@ -105,7 +105,7 @@ PUBLIC void pmacro()
error(LABEXP);
else if (symptr->type & LABIT || symptr->data & FORBIT)
error(RELAB);
- else if (pass == 0 || symptr->type & REDBIT)
+ else if (pass != last_pass || symptr->type & REDBIT)
/* copy on pass 0, also pass 1 if redefined */
{
saving = TRUE;
diff --git a/as/mops.c b/as/mops.c
index 26b0d52..d4fb4c3 100644
--- a/as/mops.c
+++ b/as/mops.c
@@ -12,7 +12,7 @@
#define is8bitadr(offset) ((offset_t) offset < 0x100)
#define is8bitsignedoffset(offset) ((offset_t) (offset) + 0x80 < 0x100)
-#define pass2 pass
+#define pass2 (pass==last_pass)
FORWARD void mshort2 P((void));
FORWARD reg_pt regchk P((void));
@@ -537,6 +537,7 @@ register struct ea_s *eap;
postb = baseind16[eap->base + 0x4 * eap->index];
}
}
+ needcpu(asize==4?3:0);
if (asize != defsize)
aprefix = 0x67;
if (eap->base == NOREG)
@@ -867,6 +868,7 @@ register struct ea_s *eap;
if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize)
oprefix = 0x66;
eap->displ = lastexp;
+ needcpu(eap->size==4?3:0);
return;
}
if (sym != lindirect)
@@ -906,6 +908,7 @@ register struct ea_s *eap;
}
if (sym == STAR)
{
+ needcpu(3);
/* context-sensitive, STAR means scaled here*/
if (eap->index == NOREG && eap->base == ESPREG)
{
@@ -958,6 +961,8 @@ register struct ea_s *eap;
eap->indcount = 0x1; /* compatibility kludge */
if (!leading_displ)
eap->displ = lastexp;
+
+ needcpu(eap->size==4?3:0);
}
PRIVATE void getimmed(eap, immed_count)
@@ -1076,7 +1081,11 @@ PUBLIC void mbcc()
kgerror(REL_REQ);
else
{
+#ifdef iscpu
+ if (iscpu(3))
+#else
if (defsize != 0x2)
+#endif
{
page = PAGE1_OPCODE;
++mcount;
@@ -1100,6 +1109,7 @@ PUBLIC void mbcc()
PUBLIC void mbswap()
{
+ needcpu(4);
++mcount;
Gd(&target);
opcode |= rm[target.base];
@@ -1192,7 +1202,8 @@ PUBLIC void mcall()
}
else if (opcode == JMP_SHORT_OPCODE)
{
- if (jumps_long)
+ if (jumps_long &&
+ (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)))
{
opcode = JMP_OPCODE;
lbranch(0x83);
@@ -1250,7 +1261,12 @@ PUBLIC void mcalli()
if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) &&
tsize == 0x2 &&
(offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
- datatoobig();
+ {
+ tsize=4;
+ if( tsize != defsize ) oprefix = 0x66;
+ /* datatoobig(); */
+ }
+ needcpu(tsize==4?3:0);
mcount += tsize;
source.size = 0x2;
buildimm(&source, FALSE);
@@ -1287,6 +1303,7 @@ PUBLIC void menter()
mcount += 2;
lastexp = target.displ; /* getimmed(&source) wiped it out */
}
+ needcpu(1);
}
/* arpl r/m16,r16 (Intel manual opcode chart wrongly says EwRw) */
@@ -1638,6 +1655,7 @@ PUBLIC void mgroup2()
opcode |= 0x2;
else if (source.displ.offset != 0x1)
{
+ needcpu(1);
opcode -= 0x10;
source.size = 0x1;
buildimm(&source, FALSE);
@@ -1649,6 +1667,7 @@ PUBLIC void mgroup2()
PUBLIC void mgroup6()
{
+ needcpu(2);
++mcount;
Ew(&target);
oprefix = 0x0;
@@ -1659,6 +1678,7 @@ PUBLIC void mgroup6()
PUBLIC void mgroup7()
{
+ needcpu(2); /* I think INVLPG is actually 386 */
++mcount;
if (opcode == 0x20 || opcode == 0x30)
{
@@ -1679,6 +1699,7 @@ PUBLIC void mgroup7()
PUBLIC void mgroup8()
{
+ needcpu(3);
++mcount;
Ev(&target);
getcomma();
@@ -1707,6 +1728,7 @@ PUBLIC void mgroup8()
PUBLIC void mGvEv()
{
+ needcpu(2);
++mcount;
Gv(&source);
getcomma();
@@ -1760,6 +1782,7 @@ PUBLIC void mimul()
yes_samesize();
if (sym != COMMA && (target.indcount != 0x0 || target.base != NOREG))
{
+ needcpu(3);
page = PAGE1_OPCODE;
++mcount;
opcode = 0xAF;
@@ -1856,6 +1879,7 @@ PUBLIC void minher32()
minher();
if (defsize != 0x4)
oprefix = 0x66;
+ needcpu(3);
}
/* AAD, AAM */
@@ -1904,16 +1928,44 @@ PUBLIC void mjcc()
kgerror(REL_REQ);
else
{
+ needcpu(3);
page = PAGE1_OPCODE;
++mcount;
opcode += 0x10;
lbranch(0x84);
}
}
- else if (jumps_long && opcode < 0x80) /* above 0x80 means loop, not long */
- mbcc();
- else
+ else if (!jumps_long || opcode > 0x80) /* above 0x80 means loop, not long */
mshort();
+ else /* mbcc */
+ {
+ getea(&target);
+ lastexp = target.displ;
+
+ if (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2))
+ {
+ if (target.indcount >= 0x2 || target.base != NOREG)
+ kgerror(REL_REQ);
+
+ aprefix = opcode ^ 0x1; /* kludged storage for short branch
+ over */
+ oprefix = defsize + 0x1;
+ mcount += 0x2;
+ opcode = JMP_OPCODE;
+ lbranch(0x83);
+ mcount -= 0x2;
+ }
+ else
+ {
+ /* 8 bit */
+ if (lastexp.data & IMPBIT)
+ {
+ error(NONIMPREQ);
+ lastexp.data = FORBIT | UNDBIT;
+ }
+ mshort2();
+ }
+ }
}
/* JCXZ, JECXZ */
@@ -1966,6 +2018,7 @@ PUBLIC void mmov()
if ((source.size = displsize(&target)) != defsize)
aprefix = 0x67;
mcount += source.size;
+ needcpu(source.size==4?3:0);
}
else if (source.base == NOREG)
{
@@ -1982,6 +2035,7 @@ PUBLIC void mmov()
{
if (isspecreg(source.base))
{
+ needcpu(3);
page = PAGE1_OPCODE;
++mcount;
opcode = 0x0;
@@ -2169,6 +2223,7 @@ PUBLIC void msetcc()
PUBLIC void mshdouble()
{
+ needcpu(3);
++mcount;
Ev(&target);
getcomma();
@@ -2834,11 +2889,17 @@ PRIVATE reg_pt regchk()
{
if (symptr->data & REGBIT)
{
+ int regno = symptr->value_reg_or_op.reg;
#ifdef I80386
- if (symptr->value_reg_or_op.reg == ST0REG && !fpreg_allowed)
+ if (regno == ST0REG && !fpreg_allowed)
error(FP_REG_NOT_ALLOWED);
+
+ /* Check cpu */
+ needcpu((regno==FSREG||regno==GSREG)?3:0);
+ needcpu((regno>=EAXREG && regno<=ESPREG)?3:0);
+ needcpu((regno>=CR0REG && regno<=TR7REG)?3:0);
#endif
- return symptr->value_reg_or_op.reg;
+ return regno;
}
}
else if (!(symptr->type & (LABIT | MACBIT | VARBIT)))
diff --git a/as/pops.c b/as/pops.c
index bc10293..2de56fe 100644
--- a/as/pops.c
+++ b/as/pops.c
@@ -31,7 +31,7 @@ int defval;
{
int newcount;
- if (flagptr->global &&pass != 0)
+ if (flagptr->global && pass == last_pass)
{
/* bump semaphore count by an expression (default 1), */
/* then set currentflag iff semaphore count is plus */
@@ -192,7 +192,7 @@ unsigned char labits;
nonimpexpres();
lastexp.data |= olddata & FORBIT; /* take all but FORBIT from
expression */
- if (oldtype & LABIT && !(olddata & UNDBIT))
+ if (oldtype & LABIT && !(olddata & UNDBIT) && !pass)
/* this is a previously defined label */
/*
@@ -228,7 +228,7 @@ unsigned char impbits;
error(ALREADY);
else if (impbits != 0)
{
- if (pass != 0)
+ if (pass == last_pass)
;
else if (symptr->type & (EXPBIT | LABIT))
symptr->type |= EXPBIT;
@@ -241,7 +241,7 @@ unsigned char impbits;
}
else
{
- if (pass != 0)
+ if (pass == last_pass)
{
if (!(symptr->type & LABIT))
error(UNLAB);
@@ -676,7 +676,7 @@ PUBLIC void pexport()
PUBLIC void pfail()
{
- if(pass) error(FAILERR);
+ if(pass==last_pass) error(FAILERR);
}
/* FCB pseudo-op */
@@ -1000,6 +1000,18 @@ PUBLIC void pwarn()
PUBLIC void puse16()
{
defsize = 2;
+#ifdef iscpu
+ if( sym != EOLSYM )
+ {
+ absexpres();
+ if (lastexp.data & UNDBIT)
+ return;
+ if( lastexp.offset > 15 )
+ setcpu((int) lastexp.offset / 100);
+ else
+ setcpu((int) lastexp.offset);
+ }
+#endif
}
/* USE16 pseudo-op */
@@ -1007,6 +1019,19 @@ PUBLIC void puse16()
PUBLIC void puse32()
{
defsize = 4;
+#ifdef iscpu
+ if(!iscpu(3)) setcpu(3);
+ if( sym != EOLSYM )
+ {
+ absexpres();
+ if (lastexp.data & UNDBIT)
+ return;
+ if( lastexp.offset > 15 )
+ setcpu((int) lastexp.offset / 100);
+ else
+ setcpu((int) lastexp.offset);
+ }
+#endif
}
#endif
@@ -1042,7 +1067,7 @@ PUBLIC void showlabel()
PRIVATE void setloc(seg)
unsigned seg;
{
- if (pass != 0 && seg != (lcdata & SEGM))
+ if (pass == last_pass && seg != (lcdata & SEGM))
putobj((opcode_pt) (seg | OBJ_SET_SEG));
{
register struct lc_s *lcp;
diff --git a/as/readsrc.c b/as/readsrc.c
index b539abd..82be10f 100644
--- a/as/readsrc.c
+++ b/as/readsrc.c
@@ -208,7 +208,7 @@ PUBLIC void pproceof()
error(EOFBLOCK);
if (iflevel != 0)
error(EOFIF);
- if (lcdata & UNDBIT)
+ if (pass && (lcdata & UNDBIT))
error(EOFLC);
lcptr->data = lcdata;
lcptr->lc = lc;
@@ -232,29 +232,40 @@ PUBLIC void pproceof()
lseek(infil, getstak->position, 0);
#endif
}
- else if (!pass)
+ else if (pass!=last_pass)
{
- pass = TRUE;
- objheader(); /* while pass 1 data all valid */
+ pass++;
+ if( last_pass>2 && last_pass<30 && dirty_pass && pass==last_pass )
+ last_pass++;
+
+ if( pass==last_pass )
+ objheader(); /* while pass 1 data all valid */
binmbuf = 0; /* reset zero variables */
maclevel = iflevel = blocklevel =
totwarn = toterr = linum = macnum = 0;
initp1p2(); /* reset other varaiables */
- binaryc = binaryg;
+ if(pass==last_pass)
+ binaryc = binaryg;
#ifdef I80386
defsize = idefsize;
+ cpuid = origcpuid;
#endif
- list.current = list.global;
- maclist.current = maclist.global;
+ if(pass==last_pass)
+ {
+ list.current = list.global;
+ maclist.current = maclist.global;
+ warn.current = TRUE;
+ if (warn.semaphore < 0)
+ warn.current = FALSE;
+ }
- warn.current = TRUE;
- if (warn.semaphore < 0)
- warn.current = FALSE;
if (infiln != 0)
infil = open_input(filnamptr);
else
eol_ptr=0;
- binheader();
+
+ if(pass==last_pass)
+ binheader();
}
else
finishup();