-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement
m_or
, m_and
, m_xor
, m_c_or
, m_c_and
, `m_c_x…
…or`, Matchers
- Loading branch information
1 parent
d5ada89
commit c42e80e
Showing
7 changed files
with
220 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use std::collections::HashMap; | ||
|
||
use gitql_core::signature::Function; | ||
use gitql_core::signature::Signature; | ||
use gitql_core::values::base::Value; | ||
|
||
use crate::functions::binary_matcher_signature; | ||
use crate::functions::binary_matchers_sides; | ||
use crate::ir::values::InstMatcherValue; | ||
use crate::matchers::binary::BinaryInstMatcher; | ||
|
||
#[inline(always)] | ||
pub fn register_binary_inst_matchers_functions(map: &mut HashMap<&'static str, Function>) { | ||
map.insert("m_or", match_or_inst); | ||
map.insert("m_and", match_and_inst); | ||
map.insert("m_xor", match_xor_inst); | ||
|
||
map.insert("m_c_or", match_commutatively_or_inst); | ||
map.insert("m_c_and", match_commutatively_and_inst); | ||
map.insert("m_c_xor", match_commutatively_xor_inst); | ||
} | ||
|
||
#[inline(always)] | ||
pub fn register_binary_inst_matchers_function_signatures( | ||
map: &mut HashMap<&'static str, Signature>, | ||
) { | ||
map.insert("m_or", binary_matcher_signature()); | ||
map.insert("m_and", binary_matcher_signature()); | ||
map.insert("m_xor", binary_matcher_signature()); | ||
|
||
map.insert("m_c_or", binary_matcher_signature()); | ||
map.insert("m_c_and", binary_matcher_signature()); | ||
map.insert("m_c_xor", binary_matcher_signature()); | ||
} | ||
|
||
fn match_or_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> { | ||
let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values); | ||
let matcher = BinaryInstMatcher::create_or(lhs_matcher, rhs_matcher); | ||
Box::new(InstMatcherValue { matcher }) | ||
} | ||
|
||
fn match_and_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> { | ||
let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values); | ||
let matcher = BinaryInstMatcher::create_and(lhs_matcher, rhs_matcher); | ||
Box::new(InstMatcherValue { matcher }) | ||
} | ||
|
||
fn match_xor_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> { | ||
let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values); | ||
let matcher = BinaryInstMatcher::create_xor(lhs_matcher, rhs_matcher); | ||
Box::new(InstMatcherValue { matcher }) | ||
} | ||
|
||
fn match_commutatively_or_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> { | ||
let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values); | ||
let matcher = BinaryInstMatcher::create_commutatively_or(lhs_matcher, rhs_matcher); | ||
Box::new(InstMatcherValue { matcher }) | ||
} | ||
|
||
fn match_commutatively_and_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> { | ||
let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values); | ||
let matcher = BinaryInstMatcher::create_commutatively_and(lhs_matcher, rhs_matcher); | ||
Box::new(InstMatcherValue { matcher }) | ||
} | ||
|
||
fn match_commutatively_xor_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> { | ||
let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values); | ||
let matcher = BinaryInstMatcher::create_commutatively_xor(lhs_matcher, rhs_matcher); | ||
Box::new(InstMatcherValue { matcher }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
pub mod arithmetic; | ||
pub mod binary; | ||
pub mod constants; | ||
pub mod fcmp; | ||
pub mod icmp; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
use inkwell::llvm_sys::core::LLVMGetInstructionOpcode; | ||
use inkwell::llvm_sys::core::LLVMGetOperand; | ||
use inkwell::llvm_sys::prelude::LLVMValueRef; | ||
use inkwell::llvm_sys::LLVMOpcode; | ||
|
||
use super::InstMatcher; | ||
|
||
#[derive(Clone)] | ||
pub enum BinaryOperator { | ||
And, | ||
Or, | ||
Xor, | ||
} | ||
|
||
impl BinaryOperator { | ||
pub fn llvm_opcode(&self) -> LLVMOpcode { | ||
match self { | ||
BinaryOperator::And => LLVMOpcode::LLVMAnd, | ||
BinaryOperator::Or => LLVMOpcode::LLVMOr, | ||
BinaryOperator::Xor => LLVMOpcode::LLVMXor, | ||
} | ||
} | ||
} | ||
|
||
/// General Binary Instruction Matcher | ||
#[derive(Clone)] | ||
pub struct BinaryInstMatcher { | ||
pub lhs_matcher: Box<dyn InstMatcher>, | ||
pub rhs_matcher: Box<dyn InstMatcher>, | ||
pub operator: BinaryOperator, | ||
pub commutatively: bool, | ||
} | ||
|
||
impl BinaryInstMatcher { | ||
pub fn create_and( | ||
lhs: Box<dyn InstMatcher>, | ||
rhs: Box<dyn InstMatcher>, | ||
) -> Box<dyn InstMatcher> { | ||
Box::new(BinaryInstMatcher { | ||
lhs_matcher: lhs, | ||
rhs_matcher: rhs, | ||
operator: BinaryOperator::Or, | ||
commutatively: false, | ||
}) | ||
} | ||
|
||
pub fn create_or(lhs: Box<dyn InstMatcher>, rhs: Box<dyn InstMatcher>) -> Box<dyn InstMatcher> { | ||
Box::new(BinaryInstMatcher { | ||
lhs_matcher: lhs, | ||
rhs_matcher: rhs, | ||
operator: BinaryOperator::And, | ||
commutatively: false, | ||
}) | ||
} | ||
|
||
pub fn create_xor( | ||
lhs: Box<dyn InstMatcher>, | ||
rhs: Box<dyn InstMatcher>, | ||
) -> Box<dyn InstMatcher> { | ||
Box::new(BinaryInstMatcher { | ||
lhs_matcher: lhs, | ||
rhs_matcher: rhs, | ||
operator: BinaryOperator::Xor, | ||
commutatively: false, | ||
}) | ||
} | ||
|
||
pub fn create_commutatively_and( | ||
lhs: Box<dyn InstMatcher>, | ||
rhs: Box<dyn InstMatcher>, | ||
) -> Box<dyn InstMatcher> { | ||
Box::new(BinaryInstMatcher { | ||
lhs_matcher: lhs, | ||
rhs_matcher: rhs, | ||
operator: BinaryOperator::Or, | ||
commutatively: true, | ||
}) | ||
} | ||
|
||
pub fn create_commutatively_or( | ||
lhs: Box<dyn InstMatcher>, | ||
rhs: Box<dyn InstMatcher>, | ||
) -> Box<dyn InstMatcher> { | ||
Box::new(BinaryInstMatcher { | ||
lhs_matcher: lhs, | ||
rhs_matcher: rhs, | ||
operator: BinaryOperator::And, | ||
commutatively: true, | ||
}) | ||
} | ||
|
||
pub fn create_commutatively_xor( | ||
lhs: Box<dyn InstMatcher>, | ||
rhs: Box<dyn InstMatcher>, | ||
) -> Box<dyn InstMatcher> { | ||
Box::new(BinaryInstMatcher { | ||
lhs_matcher: lhs, | ||
rhs_matcher: rhs, | ||
operator: BinaryOperator::Xor, | ||
commutatively: true, | ||
}) | ||
} | ||
} | ||
|
||
impl InstMatcher for BinaryInstMatcher { | ||
#[allow(clippy::not_unsafe_ptr_arg_deref)] | ||
fn is_match(&self, instruction: LLVMValueRef) -> bool { | ||
unsafe { | ||
let opcode = LLVMGetInstructionOpcode(instruction); | ||
if opcode == self.operator.llvm_opcode() { | ||
let rhs = LLVMGetOperand(instruction, 1); | ||
let lhs = LLVMGetOperand(instruction, 0); | ||
|
||
if self.lhs_matcher.is_match(lhs) && self.rhs_matcher.is_match(rhs) { | ||
return true; | ||
} | ||
|
||
if self.commutatively | ||
&& self.lhs_matcher.is_match(rhs) | ||
&& self.rhs_matcher.is_match(lhs) | ||
{ | ||
return true; | ||
} | ||
} | ||
false | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,3 +44,4 @@ pub mod other; | |
pub mod shifts; | ||
pub mod types; | ||
pub mod usage; | ||
pub mod binary; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters