from operator import or_, xor, and_, not_
 
 from nmigen import (Signal, Const)
-from nmigen.hdl.ast import UserValue
+from nmigen.hdl.ast import UserValue, Shape
 
 
 def getsig(op1):
     # TODO, http://bugs.libre-riscv.org/show_bug.cgi?id=716
     # def __getitem__(self, key):
 
-    # TODO, http://bugs.libre-riscv.org/show_bug.cgi?id=719
-    #def as_unsigned(self):
-    #def as_signed(self):
+    def __new_sign(self, signed):
+        shape = Shape(len(self), signed=signed)
+        result = PartitionedSignal.like(self, shape=shape)
+        self.m.d.comb += result.sig.eq(self.sig)
+        return result
+
+    def as_unsigned(self):
+        return self.__new_sign(False)
+    def as_signed(self):
+        return self.__new_sign(True)
 
     # useful operators
 
 
         self.add_carry_out = Signal(len(partpoints)+1)
         self.sub_carry_out = Signal(len(partpoints)+1)
         self.neg_output = Signal(width)
+        self.signed_output = Signal(width)
         self.xor_output = Signal(len(partpoints)+1)
         self.bool_output = Signal(len(partpoints)+1)
         self.all_output = Signal(len(partpoints)+1)
                                            self.carry_in)
         comb += self.sub_output.eq(sub_out.sig)
         comb += self.sub_carry_out.eq(sub_carry)
-        # neg
+        # neg / signed / unsigned
         comb += self.neg_output.eq((-self.a).sig)
+        comb += self.signed_output.eq(self.a.as_signed())
         # horizontal operators
         comb += self.xor_output.eq(self.a.xor())
         comb += self.bool_output.eq(self.a.bool())
                 a = (a & mask) >> pos  # shift it to the beginning
                 return ((-a) << pos) & mask, 0  # negate and shift it back
 
+            def test_signed_fn(carry_in, a, b, mask):
+                return a & mask, 0
+
             def test_op(msg_prefix, carry, test_fn, mod_attr, *mask_list):
                 rand_data = []
                 for i in range(100):
                                         (test_add_fn, "add"),
                                         (test_sub_fn, "sub"),
                                         (test_neg_fn, "neg"),
+                                        (test_signed_fn, "signed"),
                                         ):
                 yield part_mask.eq(0)
                 yield from test_op("16-bit", 1, test_fn, mod_attr, 0xFFFF)