From 5101a8f75152a41e84afd0311acb868bccacd61e Mon Sep 17 00:00:00 2001 From: Jeremiah Orians Date: Mon, 30 May 2016 17:52:42 -0400 Subject: [PATCH] Expanded 4OP implementation and its matching documentation --- ISA_HEX_Map.txt | 24 +++++ vm.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 255 insertions(+), 4 deletions(-) diff --git a/ISA_HEX_Map.txt b/ISA_HEX_Map.txt index 8794a9b..44f1861 100644 --- a/ISA_HEX_Map.txt +++ b/ISA_HEX_Map.txt @@ -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 diff --git a/vm.c b/vm.c index cf70bc2..5ea1607 100644 --- a/vm.c +++ b/vm.c @@ -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;