swamp_code_gen/
equal.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5//! equality functions for the emitter
6//!
7use crate::code_bld::CodeBuilder;
8use crate::ctx::Context;
9use crate::{FlagState, FlagStateKind};
10use source_map_node::Node;
11use swamp_vm_types::PointerLocation;
12use swamp_vm_types::types::{BasicTypeKind, TypedRegister};
13
14impl CodeBuilder<'_> {
15    pub fn emit_equality_to_bool_target(
16        &mut self,
17        dest_bool_reg: &TypedRegister,
18        left_source: &TypedRegister,
19        is_equal: bool,
20        right_source: &TypedRegister,
21        node: &Node,
22        ctx: &Context,
23    ) -> FlagState {
24        let polarity = match (
25            &left_source.ty.basic_type.kind,
26            &right_source.ty.basic_type.kind,
27        ) {
28            (BasicTypeKind::U8, BasicTypeKind::U8)
29            | (BasicTypeKind::B8, BasicTypeKind::B8)
30            | (BasicTypeKind::S32, BasicTypeKind::S32)
31            | (BasicTypeKind::Fixed32, BasicTypeKind::Fixed32) => {
32                self.emit_binary_operator_equal_reg(dest_bool_reg, left_source, node, right_source)
33            }
34            // Any comparison involving StringStorage: do content comparison
35            // TODO: All vec liked should use this
36            (
37                BasicTypeKind::StringView { .. } | BasicTypeKind::StringStorage { .. },
38                BasicTypeKind::StringView { .. } | BasicTypeKind::StringStorage { .. },
39            ) => {
40                let left_source_ptr_reg = PointerLocation::new(left_source.clone());
41                let right_source_ptr_reg = PointerLocation::new(right_source.clone());
42                self.emit_binary_operator_block_cmp_vec_like(
43                    dest_bool_reg,
44                    &left_source_ptr_reg,
45                    node,
46                    &right_source_ptr_reg,
47                )
48            }
49            (BasicTypeKind::TaggedUnion(a), BasicTypeKind::TaggedUnion(b)) => {
50                // TODO: Make simpler case if enum variants are without payload
51                // a.are_all_variants_without_payload()
52
53                self.emit_binary_operator_block_cmp(dest_bool_reg, left_source, node, right_source)
54            }
55            _ => {
56                self.emit_binary_operator_block_cmp(dest_bool_reg, left_source, node, right_source)
57            }
58        };
59
60        if is_equal {
61            polarity
62        } else {
63            polarity.invert_polarity()
64        }
65    }
66
67    fn emit_binary_operator_equal_reg(
68        &mut self,
69        dest_bool_reg: &TypedRegister,
70        left_source: &TypedRegister,
71        node: &Node,
72        right_source: &TypedRegister,
73    ) -> FlagState {
74        self.builder.add_cmp_reg(
75            dest_bool_reg,
76            left_source,
77            right_source,
78            node,
79            "compare reg and set result to bool reg",
80        );
81
82        FlagState {
83            kind: FlagStateKind::TFlagIsTrueWhenSet,
84        }
85    }
86
87    fn emit_binary_operator_block_cmp(
88        &mut self,
89        dest_bool_reg: &TypedRegister,
90        left_source: &TypedRegister,
91        node: &Node,
92        right_source: &TypedRegister,
93    ) -> FlagState {
94        self.builder.add_block_cmp(
95            dest_bool_reg,
96            left_source,
97            right_source,
98            left_source.size(),
99            node,
100            "compare block",
101        );
102
103        FlagState {
104            kind: FlagStateKind::TFlagIsTrueWhenSet,
105        }
106    }
107
108    fn emit_binary_operator_block_cmp_vec_like(
109        &mut self,
110        dest_bool_reg: &TypedRegister,
111        left_source: &PointerLocation,
112        node: &Node,
113        right_source: &PointerLocation,
114    ) -> FlagState {
115        self.builder.add_vec_cmp(
116            dest_bool_reg,
117            &left_source.ptr_reg,
118            &right_source.ptr_reg,
119            node,
120            "compare vec like",
121        );
122
123        FlagState {
124            kind: FlagStateKind::TFlagIsTrueWhenSet,
125        }
126    }
127}