forked from M-Labs/artiq
py2llvm/base_types: fix corner cases with bool/int/float conversion
This commit is contained in:
parent
2e45d7267d
commit
80f4bc7741
|
@ -65,7 +65,11 @@ class VInt(VGeneric):
|
||||||
def o_float(self, builder):
|
def o_float(self, builder):
|
||||||
r = VFloat()
|
r = VFloat()
|
||||||
if builder is not None:
|
if builder is not None:
|
||||||
r.auto_store(builder, builder.sitofp(self.auto_load(builder),
|
if isinstance(self, VBool):
|
||||||
|
cf = builder.uitofp
|
||||||
|
else:
|
||||||
|
cf = builder.sitofp
|
||||||
|
r.auto_store(builder, cf(self.auto_load(builder),
|
||||||
r.get_llvm_type()))
|
r.get_llvm_type()))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
@ -92,8 +96,12 @@ class VInt(VGeneric):
|
||||||
builder, builder.trunc(self.auto_load(builder),
|
builder, builder.trunc(self.auto_load(builder),
|
||||||
r.get_llvm_type()))
|
r.get_llvm_type()))
|
||||||
if self.nbits < target_bits:
|
if self.nbits < target_bits:
|
||||||
|
if isinstance(self, VBool):
|
||||||
|
ef = builder.zext
|
||||||
|
else:
|
||||||
|
ef = builder.sext
|
||||||
r.auto_store(
|
r.auto_store(
|
||||||
builder, builder.sext(self.auto_load(builder),
|
builder, ef(self.auto_load(builder),
|
||||||
r.get_llvm_type()))
|
r.get_llvm_type()))
|
||||||
return r
|
return r
|
||||||
o_roundx = o_intx
|
o_roundx = o_intx
|
||||||
|
@ -106,11 +114,15 @@ class VInt(VGeneric):
|
||||||
else:
|
else:
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
def _make_vint_binop_method(builder_name, bool_op):
|
||||||
def _make_vint_binop_method(builder_name):
|
|
||||||
def binop_method(self, other, builder):
|
def binop_method(self, other, builder):
|
||||||
if isinstance(other, VInt):
|
if isinstance(other, VInt):
|
||||||
target_bits = max(self.nbits, other.nbits)
|
target_bits = max(self.nbits, other.nbits)
|
||||||
|
if not bool_op and target_bits == 1:
|
||||||
|
target_bits = 32
|
||||||
|
if bool_op and target_bits == 1:
|
||||||
|
r = VBool()
|
||||||
|
else:
|
||||||
r = VInt(target_bits)
|
r = VInt(target_bits)
|
||||||
if builder is not None:
|
if builder is not None:
|
||||||
left = self.o_intx(target_bits, builder)
|
left = self.o_intx(target_bits, builder)
|
||||||
|
@ -124,15 +136,15 @@ def _make_vint_binop_method(builder_name):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
return binop_method
|
return binop_method
|
||||||
|
|
||||||
for _method_name, _builder_name in (("o_add", "add"),
|
for _method_name, _builder_name, _bool_op in (("o_add", "add", False),
|
||||||
("o_sub", "sub"),
|
("o_sub", "sub", False),
|
||||||
("o_mul", "mul"),
|
("o_mul", "mul", False),
|
||||||
("o_floordiv", "sdiv"),
|
("o_floordiv", "sdiv", False),
|
||||||
("o_mod", "srem"),
|
("o_mod", "srem", False),
|
||||||
("o_and", "and_"),
|
("o_and", "and_", True),
|
||||||
("o_xor", "xor"),
|
("o_xor", "xor", True),
|
||||||
("o_or", "or_")):
|
("o_or", "or_", True)):
|
||||||
setattr(VInt, _method_name, _make_vint_binop_method(_builder_name))
|
setattr(VInt, _method_name, _make_vint_binop_method(_builder_name, _bool_op))
|
||||||
|
|
||||||
|
|
||||||
def _make_vint_cmp_method(icmp_val):
|
def _make_vint_cmp_method(icmp_val):
|
||||||
|
|
Loading…
Reference in New Issue