swamp_code_gen/
relational.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 */
5use crate::code_bld::CodeBuilder;
6use crate::{FlagState, FlagStateKind};
7use swamp_semantic::{BinaryOperator, BinaryOperatorKind};
8use swamp_vm_types::types::{BasicTypeKind, TypedRegister};
9
10impl CodeBuilder<'_> {
11    pub fn emit_binary_operator_relational_i32_to_t_flag_only(
12        &mut self,
13        dest_bool_reg: &TypedRegister,
14        left_source: &TypedRegister,
15        binary_operator: &BinaryOperator,
16        right_source: &TypedRegister,
17    ) -> FlagState {
18        let node = &binary_operator.node;
19        match &binary_operator.kind {
20            BinaryOperatorKind::LessThan => {
21                self.builder
22                    .add_lt_i32(dest_bool_reg, left_source, right_source, node, "i32 lt");
23            }
24            BinaryOperatorKind::LessEqual => {
25                self.builder
26                    .add_le_i32(dest_bool_reg, left_source, right_source, node, "i32 le");
27            }
28            BinaryOperatorKind::GreaterThan => {
29                self.builder
30                    .add_gt_i32(dest_bool_reg, left_source, right_source, node, "i32 gt");
31            }
32            BinaryOperatorKind::GreaterEqual => {
33                self.builder
34                    .add_ge_i32(dest_bool_reg, left_source, right_source, node, "i32 ge");
35            }
36            _ => {
37                panic!("was not a condition")
38            }
39        }
40        FlagState {
41            kind: FlagStateKind::TFlagIsTrueWhenSet,
42        }
43    }
44
45    pub fn emit_binary_operator_relational_u8(
46        &mut self,
47        dest_bool_reg: &TypedRegister,
48        left_source: &TypedRegister,
49        binary_operator: &BinaryOperator,
50        right_source: &TypedRegister,
51    ) -> FlagState {
52        let node = &binary_operator.node;
53        match &binary_operator.kind {
54            BinaryOperatorKind::LessThan => {
55                self.builder
56                    .add_lt_u32(dest_bool_reg, left_source, right_source, node, "i32 lt");
57            }
58            BinaryOperatorKind::LessEqual => {
59                self.builder
60                    .add_le_u32(dest_bool_reg, left_source, right_source, node, "i32 le");
61            }
62            BinaryOperatorKind::GreaterThan => {
63                self.builder
64                    .add_gt_u32(dest_bool_reg, left_source, right_source, node, "i32 gt");
65            }
66            BinaryOperatorKind::GreaterEqual => {
67                self.builder
68                    .add_ge_u32(dest_bool_reg, left_source, right_source, node, "i32 ge");
69            }
70            _ => {
71                panic!("was not a condition")
72            }
73        }
74        FlagState {
75            kind: FlagStateKind::TFlagIsTrueWhenSet,
76        }
77    }
78
79    pub fn emit_binary_operator_relational_f32_to_t_flag_only(
80        &mut self,
81        dest_bool_reg: &TypedRegister,
82        left_source: &TypedRegister,
83        binary_operator: &BinaryOperator,
84        right_source: &TypedRegister,
85    ) -> FlagState {
86        let node = &binary_operator.node;
87        match &binary_operator.kind {
88            BinaryOperatorKind::LessThan => {
89                self.builder
90                    .add_lt_i32(dest_bool_reg, left_source, right_source, node, "f32 lt");
91            }
92            BinaryOperatorKind::LessEqual => {
93                self.builder
94                    .add_le_i32(dest_bool_reg, left_source, right_source, node, "f32 le");
95            }
96            BinaryOperatorKind::GreaterThan => {
97                self.builder
98                    .add_gt_i32(dest_bool_reg, left_source, right_source, node, "f32 gt");
99            }
100            BinaryOperatorKind::GreaterEqual => {
101                self.builder
102                    .add_ge_i32(dest_bool_reg, left_source, right_source, node, "f32 ge");
103            }
104            _ => panic!("not a relational operator"),
105        }
106        FlagState {
107            kind: FlagStateKind::TFlagIsTrueWhenSet,
108        }
109    }
110
111    pub fn emit_binary_operator_relational(
112        &mut self,
113        dest_bool_reg: &TypedRegister,
114        left_source: &TypedRegister,
115        binary_operator: &BinaryOperator,
116        right_source: &TypedRegister,
117    ) -> FlagState {
118        match &left_source.ty.basic_type.kind {
119            BasicTypeKind::S32 => self.emit_binary_operator_relational_i32_to_t_flag_only(
120                dest_bool_reg,
121                left_source,
122                binary_operator,
123                right_source,
124            ),
125            BasicTypeKind::Fixed32 => self.emit_binary_operator_relational_f32_to_t_flag_only(
126                dest_bool_reg,
127                left_source,
128                binary_operator,
129                right_source,
130            ),
131            BasicTypeKind::U8 => self.emit_binary_operator_relational_u8(
132                dest_bool_reg,
133                left_source,
134                binary_operator,
135                right_source,
136            ),
137            _ => panic!("this is not a relational operator type"),
138        }
139    }
140}