mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 07:49:17 +03:00
Add Lowlevel::Not
This commit is contained in:
parent
214ee6ed8e
commit
3c01ae10c6
@ -1164,6 +1164,23 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
fn build_not(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
|
||||
match *arg_layout {
|
||||
Layout::BOOL => {
|
||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
|
||||
|
||||
// Not would usually be implemented as `xor src, -1` followed by `and src, 1`
|
||||
// but since our booleans are represented as `0x101010101010101` currently, we can simply XOR with that
|
||||
let bool_val = [true as u8; 8];
|
||||
ASM::mov_reg64_imm64(&mut self.buf, dst_reg, i64::from_ne_bytes(bool_val));
|
||||
ASM::xor_reg64_reg64_reg64(&mut self.buf, src_reg, src_reg, dst_reg);
|
||||
ASM::mov_reg64_reg64(&mut self.buf, dst_reg, src_reg);
|
||||
}
|
||||
x => todo!("Not: layout, {:?}", x),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_num_lt(
|
||||
&mut self,
|
||||
dst: &Symbol,
|
||||
|
@ -649,6 +649,15 @@ trait Backend<'a> {
|
||||
);
|
||||
self.build_or(sym, &args[0], &args[1], &arg_layouts[0])
|
||||
}
|
||||
LowLevel::Not => {
|
||||
debug_assert_eq!(1, args.len(), "Not: expected to have exactly one argument");
|
||||
debug_assert_eq!(
|
||||
Layout::BOOL,
|
||||
*ret_layout,
|
||||
"Not: expected to have return layout of type Bool"
|
||||
);
|
||||
self.build_not(sym, &args[0], &arg_layouts[0])
|
||||
}
|
||||
LowLevel::NumLt => {
|
||||
debug_assert_eq!(
|
||||
2,
|
||||
@ -1048,6 +1057,9 @@ trait Backend<'a> {
|
||||
/// build_or stores the result of `src1 || src2` into dst.
|
||||
fn build_or(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, arg_layout: &InLayout<'a>);
|
||||
|
||||
/// build_not stores the result of `!src` into dst.
|
||||
fn build_not(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>);
|
||||
|
||||
/// build_num_lt stores the result of `src1 < src2` into dst.
|
||||
fn build_num_lt(
|
||||
&mut self,
|
||||
|
@ -129,6 +129,16 @@ fn or_bool() {
|
||||
assert_evals_to!("Bool.false || Bool.false", false, bool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||
fn not_bool() {
|
||||
assert_evals_to!("!Bool.true", false, bool);
|
||||
assert_evals_to!("!Bool.false", true, bool);
|
||||
|
||||
assert_evals_to!("!(!Bool.true)", true, bool);
|
||||
assert_evals_to!("!(!Bool.false)", false, bool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn empty_record() {
|
||||
|
Loading…
Reference in New Issue
Block a user