summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2013-12-22 09:48:26 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-12-22 09:48:26 +0100
commit2c95336f19eeff761ecb858c5a2a58484bb3ceeb (patch)
treef15de7ab70a55080a62b79257e407e0f0797fc87
parent537e806f8c62b26c5d5fa912f383f4a7d558574d (diff)
downloaddev86-2c95336f19eeff761ecb858c5a2a58484bb3ceeb.tar.gz
as86: Allow rep[nz] prefix before other prefixes
Fixes LILO build.
-rw-r--r--as/asm/each.asm27
-rw-r--r--as/assemble.c35
2 files changed, 52 insertions, 10 deletions
diff --git a/as/asm/each.asm b/as/asm/each.asm
index 371b20e..ceb5e32 100644
--- a/as/asm/each.asm
+++ b/as/asm/each.asm
@@ -106,28 +106,38 @@ ror [esi*4],1
rep
ins
rep
+lock
outs
rep
movs
rep
cmps
rep
+dseg
stos
rep
scas
repe
+seg ss
ins
repe
outs
repe
+lock
+seg ss
movs
repe
cmps
repe
stos
repe
+seg ss
+seg cs
+fseg
scas
repz
+lock
+lock
ins
repz
outs
@@ -147,6 +157,23 @@ repnz
scas
repnz
cmps
+repnz
+lock
+cmps
+repnz
+seg ss
+cmps
+repnz
+cseg
+cmps
+repnz
+seg ss
+lock
+cmps
+repnz
+lock
+cseg
+cmps
ret
retf
sahf
diff --git a/as/assemble.c b/as/assemble.c
index 10349a1..7379930 100644
--- a/as/assemble.c
+++ b/as/assemble.c
@@ -10,6 +10,9 @@
PRIVATE bool_t nocolonlabel; /* set for labels not followed by ':' */
PRIVATE void (*routine) P((void));
+#ifdef I80386
+PRIVATE opcode_t rep = 0; /* which rep/repne prefix was seen */
+#endif
PRIVATE pfv rout_table[] =
{
pelse,
@@ -199,7 +202,6 @@ PUBLIC void assemble()
PRIVATE void asline()
{
register struct sym_s *symptr;
- opcode_t prevop;
postb = popflags = pcrflag =
#ifdef I80386
@@ -318,22 +320,35 @@ PRIVATE void asline()
mcount = 1;
}
}
- prevop = opcode;
opcode = symptr->value_reg_or_op.op.opcode;
#ifdef I80386
needcpu((page==0 && ((opcode&0xF0) == 0x60||(opcode&0xF6)==0xC0))?1:0);
- /* We handle "rep[ne]" refix as separate instruction; check if it's valid */
- if (prevop == 0xF2 && (opcode&0xF6) != 0xA6) /* REPNE CMPS/SCAS */
- error (REPNE_STRING);
- if (prevop == 0xF3 && !((opcode&0xFC) == 0x6C || /* REP INS/OUTS */
- (opcode&0xFC) == 0xA4 || /* REP MOVS/CMPS */
- (opcode&0xFC) == 0xAC || /* REP SCAS/LODS */
- (opcode&0xFE) == 0xAA)) /* REP STOS */
- error (REP_STRING);
#endif
routine = rout_table[symptr->value_reg_or_op.op.routine];
getsym();
(*routine)();
+#ifdef I80386
+ /* We handle "rep[ne]" refix as separate instruction; check if its use is valid */
+ if (opcode == 0xF2 || opcode == 0xF3) { /* REP */
+ rep = opcode;
+ /* Not another prefix */
+ } else if (opcode != 0x2E && /* CSEG */
+ opcode != 0x3E && /* DSEG */
+ opcode != 0x26 && /* ESEG */
+ opcode != 0x64 && /* FSEG */
+ opcode != 0x65 && /* GSEG */
+ opcode != 0x36 && /* SSEG */
+ opcode != 0xF0) { /* LOCK */
+ if (rep == 0xF2 && (opcode&0xF6) != 0xA6) /* REPNE CMPS/SCAS */
+ error (REPNE_STRING);
+ if (rep == 0xF3 && !((opcode&0xFC) == 0x6C || /* REP INS/OUTS */
+ (opcode&0xFC) == 0xA4 || /* REP MOVS/CMPS */
+ (opcode&0xFC) == 0xAC || /* REP SCAS/LODS */
+ (opcode&0xFE) == 0xAA)) /* REP STOS */
+ error (REP_STRING);
+ rep = 0;
+ }
+#endif
if (sym != EOLSYM)
error(JUNK_AFTER_OPERANDS);
#ifdef I80386