Add IDiv instruction for signed integer division
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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) }
|
||||||
|
|||||||
@@ -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)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user