realemu: implement CMPS and SCAS instructions
This commit is contained in:
parent
fcf2f14760
commit
e003d49fe1
1 changed files with 81 additions and 2 deletions
|
@ -1040,7 +1040,84 @@ opstos(Cpu *cpu, Inst *i)
|
|||
}
|
||||
aw(areg(cpu, i->alen, RDI), d->off);
|
||||
if(cx)
|
||||
aw(cx, 0);
|
||||
aw(cx, c);
|
||||
}
|
||||
|
||||
static int
|
||||
repcond(Cpu *cpu, int rep)
|
||||
{
|
||||
switch(rep){
|
||||
case OREPNE:
|
||||
return (cpu->reg[RFL] & ZF) == 0;
|
||||
case OREPE:
|
||||
default:
|
||||
return !rep || (cpu->reg[RFL] & ZF) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
opscas(Cpu *cpu, Inst *i)
|
||||
{
|
||||
Iarg *cx, *s;
|
||||
ulong c;
|
||||
long a;
|
||||
int n;
|
||||
|
||||
s = adup(i->a1);
|
||||
n = s->len;
|
||||
if(cpu->reg[RFL] & DF)
|
||||
n = -n;
|
||||
if(i->rep){
|
||||
cx = areg(cpu, i->alen, RCX);
|
||||
c = ar(cx);
|
||||
} else {
|
||||
cx = nil;
|
||||
c = 1;
|
||||
}
|
||||
a = ars(i->a2);
|
||||
while(c){
|
||||
sub(cpu->reg + RFL, a, ars(s), 0, s->len*8);
|
||||
s->off += n;
|
||||
c--;
|
||||
if(repcond(cpu, i->rep))
|
||||
break;
|
||||
}
|
||||
aw(areg(cpu, i->alen, RDI), s->off);
|
||||
if(cx)
|
||||
aw(cx, c);
|
||||
}
|
||||
|
||||
static void
|
||||
opcmps(Cpu *cpu, Inst *i)
|
||||
{
|
||||
Iarg *cx, *s, *d;
|
||||
ulong c;
|
||||
int n;
|
||||
|
||||
d = adup(i->a1);
|
||||
s = adup(i->a2);
|
||||
n = s->len;
|
||||
if(cpu->reg[RFL] & DF)
|
||||
n = -n;
|
||||
if(i->rep){
|
||||
cx = areg(cpu, i->alen, RCX);
|
||||
c = ar(cx);
|
||||
} else {
|
||||
cx = nil;
|
||||
c = 1;
|
||||
}
|
||||
while(c){
|
||||
sub(cpu->reg + RFL, ars(s), ars(d), 0, s->len*8);
|
||||
s->off += n;
|
||||
d->off += n;
|
||||
c--;
|
||||
if(repcond(cpu, i->rep))
|
||||
break;
|
||||
}
|
||||
aw(areg(cpu, i->alen, RDI), d->off);
|
||||
aw(areg(cpu, i->alen, RSI), s->off);
|
||||
if(cx)
|
||||
aw(cx, c);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1159,8 +1236,10 @@ static void (*exctab[NUMOP])(Cpu *cpu, Inst*) = {
|
|||
[OCPUID] = opcpuid,
|
||||
|
||||
[OMOVS] = opmovs,
|
||||
[OSTOS] = opstos,
|
||||
[OLODS] = oplods,
|
||||
[OSTOS] = opstos,
|
||||
[OSCAS] = opscas,
|
||||
[OCMPS] = opcmps,
|
||||
|
||||
[OIN] = opin,
|
||||
[OOUT] = opout,
|
||||
|
|
Loading…
Reference in a new issue