Skip to content
← Back

src/ir/values/compare_order_to_zero.ghul

1
namespace IR.Values is
2
use System.Reflection.Metadata.ILOpCode
3
use TypeTyped = Semantic.Types.Typed
4
use Semantic.Types.Type
5
6
class COMPARE_ORDER_TO_ZERO: Value, TypeTyped is
7
value: Value
8
actual_operation: string?
9
type: Type
10
11
is_value_type: bool => true
12
13
init(value: Value, actual_operation: string?, type: Type) is
14
super.init()
15
16
self.value = value
17
self.actual_operation = actual_operation
18
self.type = type
19
si
20
21
// How the operator maps onto a comparison against zero: which
22
// comparison to make, and whether its answer has to be flipped.
23
// `>=` is `!(x < 0)` and `<=` is `!(x > 0)`, there being no
24
// negated comparison instruction to reach for instead. `==`
25
// reads an order value as an equality test - used by `case`
26
// when it falls back to a scrutinee's `<>` in place of a
27
// missing `=~` (see CASE_MATCH_OPERAND_RESOLVER).
28
lowering: (op_code: ILOpCode, negates: bool) =>
29
if actual_operation =~ ">" then
30
(ILOpCode.CGT, false)
31
elif actual_operation =~ ">=" then
32
(ILOpCode.CLT, true)
33
elif actual_operation =~ "<" then
34
(ILOpCode.CLT, false)
35
elif actual_operation =~ "<=" then
36
(ILOpCode.CGT, true)
37
elif actual_operation =~ "==" then
38
(ILOpCode.CEQ, false)
39
else
40
throw System.Exception("unexpected compare order operation: {actual_operation}")
41
fi
42
43
gen(context: IR.CONTEXT) is
44
let (op_code, negates) = lowering
45
46
Value.gen(value, context)
47
48
let body = context.current_srm_body_emitter!
49
50
body.ldc_i4(0)
51
body.op(op_code)
52
53
if negates then
54
body.ldc_i4(0)
55
body.op(ILOpCode.CEQ)
56
fi
57
si
58
59
to_string() -> string =>
60
"compare-order-to-zero[{actual_operation}]({value})"
61
si
62
si