comparison sema/Operation.d @ 107:189c049cbfcc new_gen

Cleanup of codegen, better support for operators a few bugfixes
author Anders Halager <halager@gmail.com>
date Sun, 25 May 2008 14:40:14 +0200
parents
children ed815b31479b
comparison
equal deleted inserted replaced
103:09b4d74cb3f5 107:189c049cbfcc
1 module sema.Operation;
2
3 /// Operators
4 public enum Operator
5 {
6 Add, Sub, Mul, Div, Rem,
7 Shl, LShr, AShr,
8 And, Or, Xor,
9
10 Eq, Ne,
11 Lt, Le,
12 Gt, Ge,
13 }
14
15 /**
16 Enum for the basic builtin operations.
17
18 S for signed, U for unsigned and F for floating point.
19 **/
20 public enum BuiltinOperation
21 {
22 Add, Sub, Mul, SDiv, UDiv, FDiv, SRem, URem, FRem,
23
24 Shl, LShr, AShr,
25 And, Or, Xor,
26
27 Eq, Ne,
28 SLt, ULt, FLt, SLe, ULe, FLe,
29 SGt, UGt, FGt, SGe, UGe, FGe,
30
31 None
32 }
33
34 /**
35 Returns true if the operation has an unsigned variant.
36
37 Will only be true for the S version, so SDiv gives true, UDiv or FDiv dont.
38 **/
39 private bool hasUnsignedVariant(BuiltinOperation op)
40 {
41 alias BuiltinOperation O;
42 return op is O.SDiv
43 || op is O.SRem
44 || op is O.SLt
45 || op is O.SLe
46 || op is O.SGt
47 || op is O.SGe;
48 }
49
50 /// Same as hasUnsignedVariant, but for float variants
51 private bool hasFloatVariant(BuiltinOperation op)
52 {
53 alias BuiltinOperation O;
54 return op is O.SDiv
55 || op is O.SRem
56 || op is O.SLt
57 || op is O.SLe
58 || op is O.SGt
59 || op is O.SGe;
60 }
61
62 private BuiltinOperation OpToBI(Operator op)
63 {
64 // This is dependent on the definition of Operator
65 // Maps from an Operator to the first appropiate BuiltinOperation
66 static const BuiltinOperation[] map =
67 [
68 BuiltinOperation.Add,
69 BuiltinOperation.Sub,
70 BuiltinOperation.Mul,
71 BuiltinOperation.SDiv,
72 BuiltinOperation.SRem,
73
74 BuiltinOperation.Shl,
75 BuiltinOperation.LShr,
76 BuiltinOperation.AShr,
77 BuiltinOperation.And,
78 BuiltinOperation.Or,
79 BuiltinOperation.Xor,
80
81 BuiltinOperation.Eq,
82 BuiltinOperation.Ne,
83 BuiltinOperation.SLt,
84 BuiltinOperation.SLe,
85 BuiltinOperation.SGt,
86 BuiltinOperation.SGe,
87
88 ];
89 if (op >= Operator.Add && op <= Operator.Ge)
90 return map[op];
91
92 return BuiltinOperation.None;
93 }
94
95 /**
96 Represents an operation on to values of (potentionally) different types.
97
98 Can be either some built-in thing (addition of floats, int etc) or a user
99 defined operation (a method in a struct/class).
100 **/
101 struct Operation
102 {
103 /// Returns true if the operation is legal
104 bool isPossible() { return is_valid; }
105
106 /// True for <, <=, ==, !=, >, >=
107 bool isComparison() { return false; }
108
109 /// Built in operations like adding ints or floats
110 bool isBuiltin() { return is_bi; }
111
112 /// Get the builtin operation - only valid if isBuiltin() returns true
113 BuiltinOperation builtinOp() { return bi_op; };
114
115 /// Create builtin operation
116 static Operation builtin(Operator op, bool unsigned, bool fp)
117 {
118 assert(!(unsigned && fp), "Can't be both unsigned and a float");
119 Operation res;
120 res.is_valid = true;
121 res.is_bi = true;
122 res.bi_op = OpToBI(op);
123
124 if (unsigned && hasUnsignedVariant(res.bi_op))
125 res.bi_op += 1;
126 if (fp && hasFloatVariant(res.bi_op))
127 res.bi_op += 2;
128 return res;
129 }
130
131 private:
132 bool is_valid = false;
133 bool is_bi;
134 BuiltinOperation bi_op;
135 }
136