Expanded 4OP implementation and its matching documentation

This commit is contained in:
Jeremiah Orians 2016-05-30 17:52:42 -04:00
parent 63d9d2fb54
commit 5101a8f751
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
2 changed files with 255 additions and 4 deletions

View File

@ -4,6 +4,30 @@
# 4OP nn is the XOP, a = b OP c Cond d
01 nn ab cd # 4OP Integer group
01 00 ab cd # ADD.CI a b c d :: a = b + c + CARRY? d [signed]
01 01 ab cd # ADD.CO a b c d :: a = b + c; d = CARRY? [signed]
01 02 ab cd # ADD.CIO a b c d :: a = b + c + CARRY? d; d = CARRY? [signed]
01 03 ab cd # ADDU.CI a b c d :: a = b + c + CARRY? d [unsigned]
01 04 ab cd # ADDU.CO a b c d :: a = b + c; d = CARRY? [unsigned]
01 05 ab cd # ADDU.CIO a b c d :: a = b + c + CARRY? d; d = CARRY? [unsigned]
01 06 ab cd # SUB.BI a b c d :: a = b - c - BORROW? d [signed]
01 07 ab cd # SUB.BO a b c d :: a = b - c; d = BORROW? [signed]
01 08 ab cd # SUB.BIO a b c d :: a = b - c - BORROW? d; d = BORROW? [signed]
01 09 ab cd # SUBU.BI a b c d :: a = b - c - BORROW? d [unsigned]
01 0A ab cd # SUBU.BO a b c d :: a = b - c; d = BORROW? [unsigned]
01 0B ab cd # SUBU.BIO a b c d :: a = b - c - BORROW? d; d = BORROW? [unsigned]
01 0C ab cd # MULTIPLY a b c d :: a = MUL c d; b = MULH c d [signed]
01 0D ab cd # MULTIPLYU a b c d :: a = MUL c d; b = MULH c d [unsigned]
01 0E ab cd # DIVIDE a b c d :: a = DIV c d; b = MOD c d [signed]
01 0F ab cd # DIVIDEU a b c d :: a = DIV c d; b = MOD c d [unsigned]
01 10 ab cd # MUX a b c d :: a = (c & ~b) | (d & b)
01 11 ab cd # NMUX a b c d :: a = (c & b) | (d & ~b)
01 12 ab cd # SORT a b c d :: a = MAX(c, d); b = MIN(c, d) [signed]
01 13 ab cd # SORTU a b c d :: a = MAX(c, d); b = MIN(c, d) [unsigned]
01 14 xx xx # Reserved
...
01 FF xx xx # Reserved
02 nn ab cd # 4OP Floating group
03 nn ab cd # 4OP SIMD group
04 nn ab cd # 4OP Reserved group

235
vm.c
View File

@ -40,7 +40,234 @@ void read_instruction(struct lilith* vm, struct Instruction *current)
/* Process 4OP Integer instructions */
bool eval_4OP_Int(struct lilith* vm, struct Instruction* c)
{
return true;
int32_t tmp1, tmp2;
uint32_t utmp1, utmp2;
int64_t btmp1;
uint64_t ubtmp1;
bool C, B;
utmp1 = vm->reg[c->reg3];
C = utmp1 & Carry;
B = utmp1 & Borrow;
switch(c->raw_XOP)
{
case 0x00: /* ADD.CI */
{
break;
}
case 0x01: /* ADD.CO */
{
break;
}
case 0x02: /* ADD.CIO */
{
break;
}
case 0x03: /* ADDU.CI */
{
break;
}
case 0x04: /* ADDU.CO */
{
break;
}
case 0x05: /* ADDU.CIO */
{
break;
}
case 0x06: /* SUB.BI */
{
tmp1 = (int32_t)(vm->reg[c->reg1]);
tmp2 = (int32_t)(vm->reg[c->reg2]);
if(1 == B)
{
vm->reg[c->reg0] = tmp1 - tmp2 - 1;
}
else
{
vm->reg[c->reg0] = tmp1 - tmp2;
}
break;
}
case 0x07: /* SUB.BO */
{
btmp1 = (int64_t)(vm->reg[c->reg1]);
tmp1 = (int32_t)(vm->reg[c->reg2]);
tmp2 = (int32_t)(btmp1 - tmp1);
if(btmp1 != (tmp2 + tmp1))
{
vm->reg[c->reg3] = vm->reg[c->reg3] | Borrow;
}
else
{
vm->reg[c->reg3] = vm->reg[c->reg3] & ~(Borrow);
}
vm->reg[c->reg0] = tmp2;
break;
}
case 0x08: /* SUB.BIO */
{
btmp1 = (int64_t)(vm->reg[c->reg1]);
tmp1 = (int32_t)(vm->reg[c->reg2]);
tmp2 = (int32_t)(btmp1 - tmp1);
if(btmp1 != (tmp2 + tmp1))
{
vm->reg[c->reg3] = vm->reg[c->reg3] | Borrow;
}
else
{
vm->reg[c->reg3] = vm->reg[c->reg3] & ~(Borrow);
}
if(1 == B)
{
vm->reg[c->reg0] = tmp2 - 1;
}
else
{
vm->reg[c->reg0] = tmp2;
}
break;
}
case 0x09: /* SUBU.BI */
{
utmp1 = vm->reg[c->reg1];
utmp2 = vm->reg[c->reg2];
if(1 == B)
{
vm->reg[c->reg0] = utmp1 - utmp2 - 1;
}
else
{
vm->reg[c->reg0] = utmp1 - utmp2;
}
break;
}
case 0x0A: /* SUBU.BO */
{
utmp1 = vm->reg[c->reg1];
utmp2 = vm->reg[c->reg2];
ubtmp1 = (uint64_t)(utmp1 - utmp2);
if(utmp1 != (ubtmp1 + utmp2))
{
vm->reg[c->reg3] = vm->reg[c->reg3] | Borrow;
}
else
{
vm->reg[c->reg3] = vm->reg[c->reg3] & ~(Borrow);
}
vm->reg[c->reg0] = (utmp1 - utmp2);
break;
}
case 0x0B: /* SUBU.BIO */
{
utmp1 = vm->reg[c->reg1];
utmp2 = vm->reg[c->reg2];
ubtmp1 = (uint64_t)(utmp1 - utmp2);
if(utmp1 != (ubtmp1 + utmp2))
{
vm->reg[c->reg3] = vm->reg[c->reg3] | Borrow;
}
else
{
vm->reg[c->reg3] = vm->reg[c->reg3] & ~(Borrow);
}
if(1 == B)
{
vm->reg[c->reg0] = utmp1 - utmp2 - 1;
}
else
{
vm->reg[c->reg0] = utmp1 - utmp2;
}
break;
}
case 0x0C: /* MULTIPLY */
{
btmp1 = (int32_t)(vm->reg[c->reg2]) * (int32_t)( vm->reg[c->reg3]);
vm->reg[c->reg0] = btmp1 % 0x100000000;
vm->reg[c->reg1] = btmp1 / 0x100000000;
break;
}
case 0x0D: /* MULTIPLYU */
{
ubtmp1 = vm->reg[c->reg2] * vm->reg[c->reg3];
vm->reg[c->reg0] = ubtmp1 % 0x100000000;
vm->reg[c->reg1] = ubtmp1 / 0x100000000;
break;
}
case 0x0E: /* DIVIDE */
{
tmp1 = (int32_t)(vm->reg[c->reg2]);
tmp2 = (int32_t)(vm->reg[c->reg3]);
vm->reg[c->reg0] = tmp1 / tmp2;
vm->reg[c->reg1] = tmp1 % tmp2;
break;
}
case 0x0F: /* DIVIDEU */
{
utmp1 = vm->reg[c->reg2];
utmp2 = vm->reg[c->reg3];
vm->reg[c->reg0] = utmp1 / utmp2;
vm->reg[c->reg1] = utmp1 % utmp2;
break;
}
case 0x10: /* MUX */
{
vm->reg[c->reg0] = ((vm->reg[c->reg2] & ~(vm->reg[c->reg1])) |
(vm->reg[c->reg3] & vm->reg[c->reg1]));
break;
}
case 0x11: /* NMUX */
{
vm->reg[c->reg0] = ((vm->reg[c->reg2] & vm->reg[c->reg1]) |
(vm->reg[c->reg3] & ~(vm->reg[c->reg1])));
break;
}
case 0x12: /* SORT */
{
tmp1 = (int32_t)(vm->reg[c->reg2]);
tmp2 = (int32_t)(vm->reg[c->reg3]);
if(tmp1 > tmp2)
{
vm->reg[c->reg0] = tmp1;
vm->reg[c->reg1] = tmp2;
}
else
{
vm->reg[c->reg1] = tmp1;
vm->reg[c->reg0] = tmp2;
}
break;
}
case 0x13: /* SORTU */
{
utmp1 = vm->reg[c->reg2];
utmp2 = vm->reg[c->reg3];
if(utmp1 > utmp2)
{
vm->reg[c->reg0] = utmp1;
vm->reg[c->reg1] = utmp2;
}
else
{
vm->reg[c->reg1] = utmp1;
vm->reg[c->reg0] = utmp2;
}
break;
}
default: return true;
}
return false;
}
/* Process 3OP Integer instructions */
@ -504,7 +731,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
{
int32_t tmp1;
uint32_t utmp1;
uint8_t raw0, raw1, raw2, raw3;
uint8_t raw0, raw1;
tmp1 = (int32_t)(vm->reg[c->reg1]);
utmp1 = vm->reg[c->reg1];
@ -522,12 +749,12 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
vm->reg[c->reg0] = utmp1 + c->raw_Immediate;
break;
}
case 0x10: /* SUB */
case 0x10: /* SUBI */
{
vm->reg[c->reg0] = (int32_t)(tmp1 - c->raw_Immediate);
break;
}
case 0x11: /* SUBU */
case 0x11: /* SUBUI */
{
vm->reg[c->reg0] = utmp1 + c->raw_Immediate;
break;