Add IDiv instruction for signed integer division

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-02-25 13:44:03 -05:00
parent 5619c9dc87
commit 795a890502
7 changed files with 34 additions and 9 deletions

View File

@@ -26,15 +26,16 @@ instructions! {
SUB = 0x0001, SUB = 0x0001,
MUL = 0x0002, MUL = 0x0002,
DIV = 0x0003, DIV = 0x0003,
MOD = 0x0004, IDIV = 0x0004,
AND = 0x0005, MOD = 0x0005,
OR = 0x0006, AND = 0x0006,
XOR = 0x0007, OR = 0x0007,
SHL = 0x0008, XOR = 0x0008,
SHR = 0x0009, SHL = 0x0009,
INEG = 0x000a, SHR = 0x000a,
INV = 0x000b, INEG = 0x000b,
NOT = 0x000c, INV = 0x000c,
NOT = 0x000d,
CMPEQ = 0x1000, CMPEQ = 0x1000,
CMPLT = 0x1001, CMPLT = 0x1001,
JMP = 0x1002, JMP = 0x1002,
@@ -52,6 +53,7 @@ pub enum Inst {
Sub(Dest, Source), Sub(Dest, Source),
Mul(Dest, Source), Mul(Dest, Source),
Div(Dest, Source), Div(Dest, Source),
IDiv(Dest, Source),
Mod(Dest, Source), Mod(Dest, Source),
And(Dest, Source), And(Dest, Source),
Or(Dest, Source), Or(Dest, Source),
@@ -79,6 +81,7 @@ impl Inst {
Inst::Sub(_, _) => SUB, Inst::Sub(_, _) => SUB,
Inst::Mul(_, _) => MUL, Inst::Mul(_, _) => MUL,
Inst::Div(_, _) => DIV, Inst::Div(_, _) => DIV,
Inst::IDiv(_, _) => IDIV,
Inst::Mod(_, _) => MOD, Inst::Mod(_, _) => MOD,
Inst::And(_, _) => AND, Inst::And(_, _) => AND,
Inst::Or(_, _) => OR, Inst::Or(_, _) => OR,
@@ -106,6 +109,7 @@ impl Inst {
| Inst::Sub(dest, source) | Inst::Sub(dest, source)
| Inst::Mul(dest, source) | Inst::Mul(dest, source)
| Inst::Div(dest, source) | Inst::Div(dest, source)
| Inst::IDiv(dest, source)
| Inst::Mod(dest, source) | Inst::Mod(dest, source)
| Inst::And(dest, source) | Inst::And(dest, source)
| Inst::Or(dest, source) | Inst::Or(dest, source)

View File

@@ -95,6 +95,7 @@ impl<T> MemCursor<T>
SUB => dest_source!(Sub), SUB => dest_source!(Sub),
MUL => dest_source!(Mul), MUL => dest_source!(Mul),
DIV => dest_source!(Div), DIV => dest_source!(Div),
IDIV => dest_source!(IDiv),
MOD => dest_source!(Mod), MOD => dest_source!(Mod),
AND => dest_source!(And), AND => dest_source!(And),
OR => dest_source!(Or), OR => dest_source!(Or),

View File

@@ -284,6 +284,7 @@ impl Assemble for Inst {
Inst::Sub(v1, v2) => map_inst!(inst::SUB, v1, v2), Inst::Sub(v1, v2) => map_inst!(inst::SUB, v1, v2),
Inst::Mul(v1, v2) => map_inst!(inst::MUL, v1, v2), Inst::Mul(v1, v2) => map_inst!(inst::MUL, v1, v2),
Inst::Div(v1, v2) => map_inst!(inst::DIV, v1, v2), Inst::Div(v1, v2) => map_inst!(inst::DIV, v1, v2),
Inst::IDiv(v1, v2) => map_inst!(inst::IDIV, v1, v2),
Inst::Mod(v1, v2) => map_inst!(inst::MOD, v1, v2), Inst::Mod(v1, v2) => map_inst!(inst::MOD, v1, v2),
Inst::And(v1, v2) => map_inst!(inst::AND, v1, v2), Inst::And(v1, v2) => map_inst!(inst::AND, v1, v2),
Inst::Or(v1, v2) => map_inst!(inst::OR, v1, v2), Inst::Or(v1, v2) => map_inst!(inst::OR, v1, v2),

View File

@@ -182,6 +182,7 @@ pub enum Inst {
Sub(Value, Value), Sub(Value, Value),
Mul(Value, Value), Mul(Value, Value),
Div(Value, Value), Div(Value, Value),
IDiv(Value, Value),
Mod(Value, Value), Mod(Value, Value),
And(Value, Value), And(Value, Value),
Or(Value, Value), Or(Value, Value),
@@ -209,6 +210,7 @@ impl Inst {
| Inst::Sub(v1, v2) | Inst::Sub(v1, v2)
| Inst::Mul(v1, v2) | Inst::Mul(v1, v2)
| Inst::Div(v1, v2) | Inst::Div(v1, v2)
| Inst::IDiv(v1, v2)
| Inst::Mod(v1, v2) | Inst::Mod(v1, v2)
| Inst::And(v1, v2) | Inst::And(v1, v2)
| Inst::Or(v1, v2) | Inst::Or(v1, v2)

View File

@@ -25,6 +25,7 @@ add "ADD"
sub "SUB" sub "SUB"
mul "MUL" mul "MUL"
div "DIV" div "DIV"
idiv "IDIV"
mod "MOD" mod "MOD"
and "AND" and "AND"
or "OR" or "OR"

View File

@@ -62,13 +62,22 @@ Value -> Value:
| 'LPAREN' Value 'RPAREN' 'U16' { Value::Addr(Box::new($2), IntSize::U16) } | 'LPAREN' Value 'RPAREN' 'U16' { Value::Addr(Box::new($2), IntSize::U16) }
| 'LPAREN' Value 'RPAREN' 'U32' { Value::Addr(Box::new($2), IntSize::U32) } | 'LPAREN' Value 'RPAREN' 'U32' { Value::Addr(Box::new($2), IntSize::U32) }
| 'LPAREN' Value 'RPAREN' 'U64' { Value::Addr(Box::new($2), IntSize::U64) } | 'LPAREN' Value 'RPAREN' 'U64' { Value::Addr(Box::new($2), IntSize::U64) }
//| 'LBRACKET' ArrayValues 'RBRACKET' { Value::Array($2) }
; ;
/*
ArrayValues -> Vec<Value>:
ArrayValues Value { $1.push($2); $1 }
| { Vec::new() }
;
*/
Inst -> Inst: Inst -> Inst:
'ADD' Value 'COMMA' Value { Inst::Add($2, $4) } 'ADD' Value 'COMMA' Value { Inst::Add($2, $4) }
| 'SUB' Value 'COMMA' Value { Inst::Sub($2, $4) } | 'SUB' Value 'COMMA' Value { Inst::Sub($2, $4) }
| 'MUL' Value 'COMMA' Value { Inst::Mul($2, $4) } | 'MUL' Value 'COMMA' Value { Inst::Mul($2, $4) }
| 'DIV' Value 'COMMA' Value { Inst::Div($2, $4) } | 'DIV' Value 'COMMA' Value { Inst::Div($2, $4) }
| 'IDIV' Value 'COMMA' Value { Inst::IDiv($2, $4) }
| 'MOD' Value 'COMMA' Value { Inst::Mod($2, $4) } | 'MOD' Value 'COMMA' Value { Inst::Mod($2, $4) }
| 'AND' Value 'COMMA' Value { Inst::And($2, $4) } | 'AND' Value 'COMMA' Value { Inst::And($2, $4) }
| 'OR' Value 'COMMA' Value { Inst::Or($2, $4) } | 'OR' Value 'COMMA' Value { Inst::Or($2, $4) }

View File

@@ -155,6 +155,13 @@ impl State {
let value = self.load_dest(d)?.wrapping_div(self.load_source(s)?); let value = self.load_dest(d)?.wrapping_div(self.load_source(s)?);
self.store_dest(d, value)?; self.store_dest(d, value)?;
} }
Inst::IDiv(d, s) => {
// TODO : catch divide by zero
let dest = self.load_dest(d)? as i64;
let source = self.load_source(s)? as i64;
let value = dest.wrapping_div(source);
self.store_dest(d, value as u64)?;
}
Inst::Mod(d, s) => { Inst::Mod(d, s) => {
let value = self.load_dest(d)? % self.load_source(s)?; let value = self.load_dest(d)? % self.load_source(s)?;
self.store_dest(d, value)?; self.store_dest(d, value)?;