forked from M-Labs/artiq
compiler/ir: introduce Fraction type (incomplete)
This commit is contained in:
parent
0832507c26
commit
76cef042a5
|
@ -107,6 +107,13 @@ class Visitor:
|
||||||
fn = node.func.id
|
fn = node.func.id
|
||||||
if fn in ast_unfuns:
|
if fn in ast_unfuns:
|
||||||
return ast_unfuns[fn](self.visit_expression(node.args[0]), self.builder)
|
return ast_unfuns[fn](self.visit_expression(node.args[0]), self.builder)
|
||||||
|
elif fn == "Fraction":
|
||||||
|
r = ir_values.VFraction()
|
||||||
|
if self.builder is not None:
|
||||||
|
numerator = self.visit_expression(node.args[0])
|
||||||
|
denominator = self.visit_expression(node.args[1])
|
||||||
|
r.set_value_nd(self.builder, numerator, denominator)
|
||||||
|
return r
|
||||||
elif fn == "syscall":
|
elif fn == "syscall":
|
||||||
return self.env.syscall(node.args[0].s,
|
return self.env.syscall(node.args[0].s,
|
||||||
[self.visit_expression(expr) for expr in node.args[1:]],
|
[self.visit_expression(expr) for expr in node.args[1:]],
|
||||||
|
|
|
@ -186,6 +186,92 @@ class VBool(VInt):
|
||||||
r.set_ssa_value(builder, self.get_ssa_value(builder))
|
r.set_ssa_value(builder, self.get_ssa_value(builder))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
# Fraction type
|
||||||
|
|
||||||
|
class VFraction(_Value):
|
||||||
|
def get_llvm_type(self):
|
||||||
|
return lc.Type.vector(lc.Type.int(64), 2)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<VFraction>"
|
||||||
|
|
||||||
|
def same_type(self, other):
|
||||||
|
return isinstance(other, VFraction)
|
||||||
|
|
||||||
|
def merge(self, other):
|
||||||
|
if not isinstance(other, VFraction):
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
def _simplify(self, builder):
|
||||||
|
pass # TODO
|
||||||
|
|
||||||
|
def set_value_nd(self, builder, numerator, denominator):
|
||||||
|
numerator = numerator.o_int64(builder).get_ssa_value(builder)
|
||||||
|
denominator = denominator.o_int64(builder).get_ssa_value(builder)
|
||||||
|
value = lc.Constant.undef(lc.Type.vector(lc.Type.int(64), 2))
|
||||||
|
value = builder.insert_element(value, numerator, lc.Constant.int(lc.Type.int(), 0))
|
||||||
|
value = builder.insert_element(value, denominator, lc.Constant.int(lc.Type.int(), 1))
|
||||||
|
self.set_ssa_value(builder, value)
|
||||||
|
self._simplify(builder)
|
||||||
|
|
||||||
|
def set_value(self, builder, n):
|
||||||
|
if not isinstance(n, VFraction):
|
||||||
|
raise TypeError
|
||||||
|
self.set_ssa_value(builder, n.get_ssa_value(builder))
|
||||||
|
|
||||||
|
def o_bool(self, builder):
|
||||||
|
r = VBool()
|
||||||
|
if builder is not None:
|
||||||
|
zero = lc.Constant.int(lc.Type.int(64), 0)
|
||||||
|
numerator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 0))
|
||||||
|
r.set_ssa_value(builder, builder.icmp(lc.ICMP_NE, numerator, zero))
|
||||||
|
return r
|
||||||
|
|
||||||
|
def o_intx(self, target_bits, builder):
|
||||||
|
if builder is None:
|
||||||
|
return VInt(target_bits)
|
||||||
|
else:
|
||||||
|
r = VInt(64)
|
||||||
|
numerator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 0))
|
||||||
|
denominator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 1))
|
||||||
|
r.set_ssa_value(builder, builder.sdiv(numerator, denominator))
|
||||||
|
return r.o_intx(target_bits, builder)
|
||||||
|
|
||||||
|
def o_roundx(self, target_bits, builder):
|
||||||
|
if builder is None:
|
||||||
|
return VInt(target_bits)
|
||||||
|
else:
|
||||||
|
r = VInt(64)
|
||||||
|
numerator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 0))
|
||||||
|
denominator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 1))
|
||||||
|
h_denominator = builder.ashr(denominator, lc.Constant.int(lc.Type.int(), 1))
|
||||||
|
r_numerator = builder.add(numerator, h_denominator)
|
||||||
|
r.set_ssa_value(builder, builder.sdiv(r_numerator, denominator))
|
||||||
|
return r.o_intx(target_bits, builder)
|
||||||
|
|
||||||
|
def _o_eq_inv(self, other, builder, invert):
|
||||||
|
if isinstance(other, VFraction):
|
||||||
|
r = VBool()
|
||||||
|
if builder is not None:
|
||||||
|
ee = []
|
||||||
|
for i in range(2):
|
||||||
|
es = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), i))
|
||||||
|
eo = builder.extract_element(other.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), i))
|
||||||
|
ee.append(builder.icmp(lc.ICMP_EQ, es, eo))
|
||||||
|
ssa_r = builder.and_(ee[0], ee[1])
|
||||||
|
if invert:
|
||||||
|
ssa_r = builder.xor(ssa_r, lc.Constant.int(lc.Type.int(1), 1))
|
||||||
|
r.set_ssa_value(builder, ssa_r)
|
||||||
|
return r
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def o_eq(self, other, builder):
|
||||||
|
return self._o_eq_inv(other, builder, False)
|
||||||
|
|
||||||
|
def o_ne(self, other, builder):
|
||||||
|
return self._o_eq_inv(other, builder, True)
|
||||||
|
|
||||||
# Operators
|
# Operators
|
||||||
|
|
||||||
def _make_unary_operator(op_name):
|
def _make_unary_operator(op_name):
|
||||||
|
|
Loading…
Reference in New Issue