realemu: implement IDIV, mark 0xE0000 writeable, fix DIV overfow trap
This commit is contained in:
parent
08bb4afb52
commit
1fe36bf849
1 changed files with 49 additions and 2 deletions
|
@ -769,12 +769,58 @@ opdiv(Cpu *cpu, Inst *i)
|
||||||
n = (uvlong)ar(ra)<<s | (uvlong)ar(qa);
|
n = (uvlong)ar(ra)<<s | (uvlong)ar(qa);
|
||||||
q = n/d;
|
q = n/d;
|
||||||
if(q > m)
|
if(q > m)
|
||||||
trap(cpu, EGPF);
|
trap(cpu, EDIV0);
|
||||||
r = n%d;
|
r = n%d;
|
||||||
aw(ra, r);
|
aw(ra, r);
|
||||||
aw(qa, q);
|
aw(qa, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
opidiv(Cpu *cpu, Inst *i)
|
||||||
|
{
|
||||||
|
Iarg *qa, *ra;
|
||||||
|
vlong n, q, min, max;
|
||||||
|
long r, d;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
s = i->a1->len*8;
|
||||||
|
d = ars(i->a1);
|
||||||
|
if(d == 0)
|
||||||
|
trap(cpu, EDIV0);
|
||||||
|
if(s == 8){
|
||||||
|
qa = areg(cpu, 1, RAX);
|
||||||
|
ra = adup(qa);
|
||||||
|
ra->tag |= TH;
|
||||||
|
} else {
|
||||||
|
qa = areg(cpu, i->olen, RAX);
|
||||||
|
ra = areg(cpu, i->olen, RDX);
|
||||||
|
}
|
||||||
|
n = (vlong)ars(ra)<<s | (uvlong)ars(qa);
|
||||||
|
q = n/d;
|
||||||
|
r = n%d;
|
||||||
|
|
||||||
|
/* check for overflow based on operand size */
|
||||||
|
switch(s) {
|
||||||
|
case 8:
|
||||||
|
min = (char)0x80;
|
||||||
|
max = 0x7F;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
min = (short)0x8000;
|
||||||
|
max = 0x7FFF;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
min = (long)0x80000000;
|
||||||
|
max = 0x7FFFFFFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(q > max || q < min)
|
||||||
|
trap(cpu, EDIV0);
|
||||||
|
|
||||||
|
aw(ra, r);
|
||||||
|
aw(qa, q);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cctrue(Cpu *cpu, Inst *i)
|
cctrue(Cpu *cpu, Inst *i)
|
||||||
|
@ -1249,6 +1295,7 @@ static void (*exctab[NUMOP])(Cpu *cpu, Inst*) = {
|
||||||
[OMUL] = opmul,
|
[OMUL] = opmul,
|
||||||
[OIMUL] = opimul,
|
[OIMUL] = opimul,
|
||||||
[ODIV] = opdiv,
|
[ODIV] = opdiv,
|
||||||
|
[OIDIV] = opidiv,
|
||||||
|
|
||||||
[OLEA] = oplea,
|
[OLEA] = oplea,
|
||||||
[OMOV] = opmov,
|
[OMOV] = opmov,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue