Esempio n. 1
0
    def data_sink(self, value):
        """
        This is a private function, you shouldn't need to call this directly.
        """

        if self.type_ == "int":

            self.l.append(value)
            self.times.append(self.chip.time)

        elif self.type_ == "long":

            if self.high_word:
                self.high_word = not self.high_word
                self.l.append(join_words(value, self.low))
                self.times.append(self.chip.time)
            else:
                self.high_word = not self.high_word
                self.low = value

        elif self.type_ == "float":

            self.l.append(bits_to_float(value))
            self.times.append(self.chip.time)

        elif self.type_ == "double":

            if self.high_word:
                self.high_word = not self.high_word
                self.l.append(bits_to_double(join_words(value, self.low)))
                self.times.append(self.chip.time)
            else:
                self.high_word = not self.high_word
                self.low = value
Esempio n. 2
0
    def simulation_step(self):
        """execute the python simulation by one step"""

        l = self.get_line()
        f = self.get_file()
        if f in self.breakpoints:
            if l in self.breakpoints[f]:
                raise BreakSim

        instruction = self.instructions[self.program_counter]
        current_stack = self.registers.get(register_map.tos, 0)
        self.max_stack = max([current_stack, self.max_stack])

        if self.profile:
            trace = instruction.get("trace", "-")
            lines = self.files.get(trace.filename, {})
            lines[trace.lineno] = lines.get(trace.lineno, 0) + 1
            self.files[trace.filename] = lines

        if "literal" in instruction:
            literal = instruction["literal"]

        if "label" in instruction:
            literal = instruction["label"]

        # read operands
        #
        a = instruction.get("a", 0)
        b = instruction.get("b", 0)
        z = instruction.get("z", 0)

        operand_b = self.registers.get(b, 0)
        operand_a = self.registers.get(a, 0)

        this_instruction = self.program_counter
        self.program_counter += 1
        wait = False
        result = None

        if instruction["op"] == "stop":
            self.program_counter = this_instruction
            wait = True
            for file_ in self.input_files.values():
                file_.close()
            for file_ in self.output_files.values():
                file_.close()
            raise StopSim

        elif instruction["op"] == "literal":
            if literal & 0x8000:
                result = -65536 | literal
            else:
                result = literal
            result &= 0xffffffff
        elif instruction["op"] == "addl":
            if literal & 0x8000:
                sext = -65536 | literal
            else:
                sext = literal
            result = sext + operand_a
            result &= 0xffffffff
        elif instruction["op"] == "literal_hi":
            if literal & 0x8000:
                sext = -65536 | literal
            else:
                sext = literal
            result = (sext << 16) | (operand_a & 0x0000ffff)
            result &= 0xffffffff
        elif instruction["op"] == "store":
            self.memory[operand_a] = operand_b
        elif instruction["op"] == "load":
            result = self.memory.get(operand_a, 0)
        elif instruction["op"] == "call":
            result = this_instruction + 1
            self.program_counter = literal
        elif instruction["op"] == "return":
            self.program_counter = operand_a
        elif instruction["op"] == "a_lo":
            result = self.a_lo
            self.a_lo = operand_a
        elif instruction["op"] == "b_lo":
            result = self.b_lo
            self.b_lo = operand_a
        elif instruction["op"] == "a_hi":
            result = self.a_hi
            self.a_hi = operand_a
        elif instruction["op"] == "b_hi":
            result = self.b_hi
            self.b_hi = operand_a
        elif instruction["op"] == "not":
            result = (~operand_a) & 0xffffffff
        elif instruction["op"] == "int_to_long":
            if operand_a & 0x80000000:
                result = 0xffffffff
            else:
                result = 0
        elif instruction["op"] == "int_to_float":
            f = float(to_32_signed(self.a_lo))
            self.a_lo = float_to_bits(f)
        elif instruction["op"] == "float_to_int":
            i = bits_to_float(self.a_lo)
            if math.isnan(i):
                self.a_lo = 0
            else:
                self.a_lo = int(i) & 0xffffffff
        elif instruction["op"] == "long_to_double":
            double = float(to_64_signed(chips_c.join_words(self.a_hi, self.a_lo)))
            if math.isnan(double):
                self.a_hi = 0
                self.a_lo = 0
            else:
                self.a_hi = chips_c.high_word(double_to_bits(double))
                self.a_lo = chips_c.low_word(double_to_bits(double))
        elif instruction["op"] == "double_to_long":
            bits = int(bits_to_double(chips_c.join_words(self.a_hi, self.a_lo)))
            bits &= 0xffffffffffffffff
            self.a_hi = chips_c.high_word(bits)
            self.a_lo = chips_c.low_word(bits)
        elif instruction["op"] == "float_to_double":
            f = bits_to_float(self.a_lo)
            bits = double_to_bits(f)
            self.a_hi = chips_c.high_word(bits)
            self.a_lo = chips_c.low_word(bits)
        elif instruction["op"] == "double_to_float":
            f = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            self.a_lo = float_to_bits(f)
        elif instruction["op"] == "add":
            total = add(operand_a, operand_b, 0);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "add_with_carry":
            total = add(operand_a, operand_b, self.carry);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "subtract":
            total = subtract(operand_a, operand_b, 1);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "subtract_with_carry":
            total = subtract(operand_a, operand_b, self.carry);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "multiply":
            lw = operand_a * operand_b
            self.carry = chips_c.high_word(lw)
            result = chips_c.low_word(lw)
        elif instruction["op"] == "divide":
            a = operand_a
            b = operand_b
            result = chips_c.divide(a, b)
        elif instruction["op"] == "unsigned_divide":
            a = operand_a
            b = operand_b
            result = chips_c.unsigned_divide(a, b)
        elif instruction["op"] == "modulo":
            a = operand_a
            b = operand_b
            result = chips_c.modulo(a, b)
        elif instruction["op"] == "unsigned_modulo":
            a = operand_a
            b = operand_b
            result = chips_c.unsigned_modulo(a, b)
        elif instruction["op"] == "long_divide":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            quotient = chips_c.long_divide(a, b)
            self.a_hi = chips_c.high_word(quotient)
            self.a_lo = chips_c.low_word(quotient)
        elif instruction["op"] == "long_modulo":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            remainder = chips_c.long_modulo(a, b)
            self.a_hi = chips_c.high_word(remainder)
            self.a_lo = chips_c.low_word(remainder)
        elif instruction["op"] == "unsigned_long_divide":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            quotient = chips_c.unsigned_long_divide(a, b)
            self.a_hi = chips_c.high_word(quotient)
            self.a_lo = chips_c.low_word(quotient)
        elif instruction["op"] == "unsigned_long_modulo":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            remainder = chips_c.unsigned_long_modulo(a, b)
            self.a_hi = chips_c.high_word(remainder)
            self.a_lo = chips_c.low_word(remainder)
        elif instruction["op"] == "carry":
            result = self.carry
        elif instruction["op"] == "or":
            result = operand_a | operand_b
        elif instruction["op"] == "and":
            result = operand_a & operand_b
        elif instruction["op"] == "xor":
            result = operand_a ^ operand_b
        elif instruction["op"] == "shift_left":
            total = shift_left(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_left_with_carry":
            total = shift_left(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_right":
            total = shift_right(operand_a, operand_b)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "unsigned_shift_right":
            total = unsigned_shift_right(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_right_with_carry":
            total = unsigned_shift_right(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "greater":
            result = greater(operand_a, operand_b)
        elif instruction["op"] == "greater_equal":
            result = greater_equal(operand_a, operand_b)
        elif instruction["op"] == "unsigned_greater":
            result = unsigned_greater(operand_a, operand_b)
        elif instruction["op"] == "unsigned_greater_equal":
            result = unsigned_greater_equal(operand_a, operand_b)
        elif instruction["op"] == "equal":
            result = operand_a == operand_b
        elif instruction["op"] == "not_equal":
            result = operand_a != operand_b
        elif instruction["op"] == "jmp_if_false":
            if operand_a == 0:
                self.program_counter = literal
        elif instruction["op"] == "jmp_if_true":
            if operand_a != 0:
                self.program_counter = literal
        elif instruction["op"] == "goto":
            self.program_counter = literal
        elif instruction["op"] == "timer_low":
            result = self.clock&0xffffffff
        elif instruction["op"] == "timer_high":
            result = self.clock>>32
        elif instruction["op"] == "file_read":
            value = self.input_files[instruction["filename"]].getline()
            result = value
        elif instruction["op"] == "float_file_write":
            self.output_files[instruction["file_name"]].write(
                "%.7f\n" %
                bits_to_float(operand_a))
        elif instruction["op"] == "unsigned_file_write":
            self.output_files[instruction["file_name"]].write(
                "%i\n" %
                operand_a)
        elif instruction["op"] == "file_write":
            self.output_files[instruction["file_name"]].write(
                "%i\n" %
                to_32_signed(operand_a))
        elif instruction["op"] == "read":
            if operand_a not in self.inputs:
                result = 0
            else:
                input_ = self.inputs[operand_a]
                if input_.src_rdy and input_.dst_rdy:
                    result = input_.q
                    input_.next_dst_rdy = False
                else:
                    input_.next_dst_rdy = True
                    wait = True
        elif instruction["op"] == "ready":
            if operand_a not in self.inputs:
                operand_a = 0
            else:
                input_ = self.inputs[operand_a]
                if input_.src_rdy:
                    result = 1
                else:
                    result = 0
        elif instruction["op"] == "output_ready":
            if operand_a not in self.outputs:
                operand_a = 0
            else:
                output_ = self.outputs[operand_a]
                if output_.dst_rdy:
                    result = 1
                else:
                    result = 0
        elif instruction["op"] == "write":
            if operand_a not in self.outputs:
                pass
            else:
                output_ = self.outputs[operand_a]
                if output_.src_rdy and output_.dst_rdy:
                    output_.next_src_rdy = False
                else:
                    output_.q = operand_b
                    output_.next_src_rdy = True
                    wait = True
        elif instruction["op"] == "float_add":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ + floatb)
        elif instruction["op"] == "float_subtract":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ - floatb)
        elif instruction["op"] == "float_multiply":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ * floatb)
        elif instruction["op"] == "float_divide":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            try:
                result = float_to_bits(float_ / floatb)
            except ZeroDivisionError:
                result = float_to_bits(float("nan"))
        elif instruction["op"] == "long_float_add":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double + doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double + doubleb))
        elif instruction["op"] == "long_float_subtract":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double - doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double - doubleb))
        elif instruction["op"] == "long_float_multiply":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double * doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double * doubleb))
        elif instruction["op"] == "long_float_divide":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            try:
                self.a_hi = chips_c.high_word(double_to_bits(double / doubleb))
                self.a_lo = chips_c.low_word(double_to_bits(double / doubleb))
            except ZeroDivisionError:
                self.a_hi = chips_c.high_word(double_to_bits(float("nan")))
                self.a_lo = chips_c.low_word(double_to_bits(float("nan")))
        elif instruction["op"] == "long_float_file_write":
            long_word = chips_c.join_words(self.a_hi, self.a_lo)
            self.output_files[instruction["file_name"]].write(
                "%.16f\n" %
                bits_to_double(long_word))
        elif instruction["op"] == "long_file_write":
            long_word = chips_c.join_words(self.a_hi, self.a_lo)
            self.output_files[instruction["file_name"]].write(
                "%f\n" %
                long_word)
        elif instruction["op"] == "assert":
            if operand_a == 0:
                raise ChipsAssertionFail(
                    instruction["file"],
                    instruction["line"])
        elif instruction["op"] == "report":
            print "%d (report (int) at line: %s in file: %s)" % (
                to_32_signed(self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_report":
            print "%d (report (long) at line: %s in file: %s)" % (
                to_64_signed(chips_c.join_words(self.a_hi, self.a_lo)),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "float_report":
            print "%f (report (float) at line: %s in file: %s)" % (
                bits_to_float(self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_float_report":
            print "%s (report (double) at line: %s in file: %s)" % (

                bits_to_double(chips_c.join_words(self.a_hi, self.a_lo)),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "unsigned_report":
            print "%d (report (unsigned) at line: %s in file: %s)" % (
                self.a_lo,
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_unsigned_report":
            print "%d (report (unsigned long) at line: %s in file: %s)" % (
                chips_c.join_words(self.a_hi, self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "wait_clocks":
            if self.timer == operand_a:
                wait = False
                self.timer = 0
            else:
                wait = True
                self.timer += 1

        else:
            print "Unknown machine instruction", instruction["op"]
            sys.exit(-1)

        # Write data back
        if result is not None:
            self.registers[z] = result

        # manipulate stack pointer
        if wait:
            self.program_counter = this_instruction

        self.clock += 1
Esempio n. 3
0
    def simulation_step(self):
        """execute the python simulation by one step"""

        l = self.get_line()
        f = self.get_file()
        if f in self.breakpoints:
            if l in self.breakpoints[f]:
                raise BreakSim

        instruction = self.instructions[self.program_counter]
        current_stack = self.registers.get(register_map.tos, 0)
        self.max_stack = max([current_stack, self.max_stack])

        if self.profile:
            trace = instruction.get("trace", "-")
            lines = self.files.get(trace.filename, {})
            lines[trace.lineno] = lines.get(trace.lineno, 0) + 1
            self.files[trace.filename] = lines

        literal = 0
        if "literal" in instruction:
            literal = instruction["literal"]

        if "label" in instruction:
            literal = instruction["label"]

        # read operands
        #
        a = instruction.get("a", 0)
        b = instruction.get("b", 0)
        z = instruction.get("z", 0)

        operand_b = self.registers.get(b, 0)
        operand_a = self.registers.get(a, 0)
        operand_z = self.registers.get(z, 0)

        this_instruction = self.program_counter
        self.program_counter += 1
        wait = False
        result = None

        unsigned_literal = literal
        #literal = interpret_twos_complement(unsigned_literal, 16)
        signed_literal = interpret_twos_complement(unsigned_literal, 16)
        if instruction["op"] == "addl":
            literal = literal & 0xffff
#        if literal < 0:
#            print(instruction["op"])

        if instruction["op"] == "stop":
            self.program_counter = this_instruction
            wait = True
            for file_ in self.input_files.values():
                file_.close()
            for file_ in self.output_files.values():
                file_.close()
            raise StopSim

        elif instruction["op"] == "literal":
            if literal & 0x8000:
                result = -65536 | literal
            else:
                result = literal
            result &= 0xffffffff
        elif instruction["op"] == "addl":
            if literal & 0x8000:
                sext = -65536 | literal
            else:
                sext = literal
            result = sext + operand_a
            result &= 0xffffffff
        elif instruction["op"] == "literal_hi":
            if literal & 0x8000:
                sext = -65536 | literal
            else:
                sext = literal
            result = (sext << 16) | (operand_a & 0x0000ffff)
            result &= 0xffffffff
        elif instruction["op"] == "store":
            offset = interpret_twos_complement(literal, 14)
            self.memory.store(operand_z + offset, operand_a)
        elif instruction["op"] == "store8":
            offset = interpret_twos_complement(literal, 14)
            self.memory.store_8(operand_z + offset, operand_a)
        elif instruction["op"] == "store16":
            offset = interpret_twos_complement(literal, 14)
            self.memory.store_16(operand_z + offset, operand_a)
        elif instruction["op"] == "load":
            result = self.memory.load(operand_a)
        elif instruction["op"] == "load_disp":
            offset = interpret_twos_complement(literal, 13)
            result = self.memory.load(operand_a + offset)
        elif instruction["op"] == "load8":
            offset = interpret_twos_complement(literal, 13)
            result = self.memory.load_8(operand_a + offset,
                    literal & 0x8000 != 0)
        elif instruction["op"] == "load16":
            offset = interpret_twos_complement(literal, 13)
            result = self.memory.load_16(operand_a + offset,
                    literal & 0x8000 != 0)
        elif instruction["op"] == "call":
            result = this_instruction + 1
            self.program_counter = literal
        elif instruction["op"] == "return":
            self.program_counter = operand_a
        elif instruction["op"] == "a_lo":
            result = self.a_lo
            self.a_lo = operand_a
        elif instruction["op"] == "b_lo":
            result = self.b_lo
            self.b_lo = operand_a
        elif instruction["op"] == "a_hi":
            result = self.a_hi
            self.a_hi = operand_a
        elif instruction["op"] == "b_hi":
            result = self.b_hi
            self.b_hi = operand_a
        elif instruction["op"] == "a_lo_in":
            self.a_lo = operand_a
        elif instruction["op"] == "b_lo_in":
            self.b_lo = operand_a
        elif instruction["op"] == "a_hi_in":
            self.a_hi = operand_a
        elif instruction["op"] == "b_hi_in":
            self.b_hi = operand_a
        elif instruction["op"] == "a_lo_out":
            result = self.a_lo
        elif instruction["op"] == "b_lo_out":
            result = self.b_lo
        elif instruction["op"] == "a_hi_out":
            result = self.a_hi
        elif instruction["op"] == "b_hi_out":
            result = self.b_hi
        elif instruction["op"] == "not":
            result = (~operand_a) & 0xffffffff
        elif instruction["op"] == "int_to_long":
            if operand_a & 0x80000000:
                result = 0xffffffff
            else:
                result = 0
        elif instruction["op"] == "int_to_float":
            f = float(to_32_signed(self.a_lo))
            self.a_lo = float_to_bits(f)
        elif instruction["op"] == "float_to_int":
            i = bits_to_float(self.a_lo)
            if math.isnan(i):
                self.a_lo = 0
            else:
                self.a_lo = int(i) & 0xffffffff
        elif instruction["op"] == "long_to_double":
            double = float(to_64_signed(chips_c.join_words(self.a_hi, self.a_lo)))
            if math.isnan(double):
                self.a_hi = 0
                self.a_lo = 0
            else:
                self.a_hi = chips_c.high_word(double_to_bits(double))
                self.a_lo = chips_c.low_word(double_to_bits(double))
        elif instruction["op"] == "double_to_long":
            bits = int(bits_to_double(chips_c.join_words(self.a_hi, self.a_lo)))
            bits &= 0xffffffffffffffff
            self.a_hi = chips_c.high_word(bits)
            self.a_lo = chips_c.low_word(bits)
        elif instruction["op"] == "float_to_double":
            f = bits_to_float(self.a_lo)
            bits = double_to_bits(f)
            self.a_hi = chips_c.high_word(bits)
            self.a_lo = chips_c.low_word(bits)
        elif instruction["op"] == "double_to_float":
            f = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            self.a_lo = float_to_bits(f)
        elif instruction["op"] == "add":
            total = add(operand_a, operand_b, 0);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "add_with_carry":
            total = add(operand_a, operand_b, self.carry);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "subtract":
            total = subtract(operand_a, operand_b, 1);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "subtract_with_carry":
            total = subtract(operand_a, operand_b, self.carry);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "multiply":
            lw = operand_a * operand_b
            self.carry = chips_c.high_word(lw)
            result = chips_c.low_word(lw)
        elif instruction["op"] == "divide":
            a = operand_a
            b = operand_b
            result = chips_c.divide(a, b)
        elif instruction["op"] == "unsigned_divide":
            a = operand_a
            b = operand_b
            result = chips_c.unsigned_divide(a, b)
        elif instruction["op"] == "modulo":
            a = operand_a
            b = operand_b
            result = chips_c.modulo(a, b)
        elif instruction["op"] == "unsigned_modulo":
            a = operand_a
            b = operand_b
            result = chips_c.unsigned_modulo(a, b)
        elif instruction["op"] == "long_divide":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            quotient = chips_c.long_divide(a, b)
            self.a_hi = chips_c.high_word(quotient)
            self.a_lo = chips_c.low_word(quotient)
        elif instruction["op"] == "long_modulo":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            remainder = chips_c.long_modulo(a, b)
            self.a_hi = chips_c.high_word(remainder)
            self.a_lo = chips_c.low_word(remainder)
        elif instruction["op"] == "unsigned_long_divide":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            quotient = chips_c.unsigned_long_divide(a, b)
            self.a_hi = chips_c.high_word(quotient)
            self.a_lo = chips_c.low_word(quotient)
        elif instruction["op"] == "unsigned_long_modulo":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            remainder = chips_c.unsigned_long_modulo(a, b)
            self.a_hi = chips_c.high_word(remainder)
            self.a_lo = chips_c.low_word(remainder)
        elif instruction["op"] == "carry":
            result = self.carry
        elif instruction["op"] == "or":
            result = operand_a | operand_b
        elif instruction["op"] == "and":
            result = operand_a & operand_b
        elif instruction["op"] == "xor":
            result = operand_a ^ operand_b
        elif instruction["op"] == "shift_left":
            total = shift_left(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_left_with_carry":
            total = shift_left(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_right":
            total = shift_right(operand_a, operand_b)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "unsigned_shift_right":
            total = unsigned_shift_right(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_right_with_carry":
            total = unsigned_shift_right(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "greater":
            result = greater(operand_a, operand_b)
        elif instruction["op"] == "greater_equal":
            result = greater_equal(operand_a, operand_b)
        elif instruction["op"] == "unsigned_greater":
            result = unsigned_greater(operand_a, operand_b)
        elif instruction["op"] == "unsigned_greater_equal":
            result = unsigned_greater_equal(operand_a, operand_b)
        elif instruction["op"] == "equal":
            result = operand_a == operand_b
        elif instruction["op"] == "not_equal":
            result = operand_a != operand_b
        elif instruction["op"] == "jmp_if_false":
            if operand_a == 0:
                self.program_counter = literal
        elif instruction["op"] == "jmp_if_true":
            if operand_a != 0:
                self.program_counter = literal
        elif instruction["op"] == "goto":
            self.program_counter = literal
        elif instruction["op"] == "timer_low":
            result = self.clock&0xffffffff
        elif instruction["op"] == "timer_high":
            result = self.clock>>32
        elif instruction["op"] == "file_read":
            value = self.input_files[instruction["filename"]].getline()
            result = value
        elif instruction["op"] == "float_file_write":
            self.output_files[instruction["file_name"]].write(
                "%.7f\n" %
                bits_to_float(operand_a))
        elif instruction["op"] == "unsigned_file_write":
            self.output_files[instruction["file_name"]].write(
                "%i\n" %
                operand_a)
        elif instruction["op"] == "file_write":
            self.output_files[instruction["file_name"]].write(
                "%i\n" %
                to_32_signed(operand_a))
        elif instruction["op"] == "read":
            if operand_a not in self.inputs:
                result = 0
            else:
                input_ = self.inputs[operand_a]
                if input_.src_rdy and input_.dst_rdy:
                    result = input_.q
                    input_.next_dst_rdy = False
                else:
                    input_.next_dst_rdy = True
                    wait = True
        elif instruction["op"] == "ready":
            if operand_a not in self.inputs:
                operand_a = 0
            else:
                input_ = self.inputs[operand_a]
                if input_.src_rdy:
                    result = 1
                else:
                    result = 0
        elif instruction["op"] == "output_ready":
            if operand_a not in self.outputs:
                operand_a = 0
            else:
                output_ = self.outputs[operand_a]
                if output_.dst_rdy:
                    result = 1
                else:
                    result = 0
        elif instruction["op"] == "write":
            if operand_a not in self.outputs:
                pass
            else:
                output_ = self.outputs[operand_a]
                if output_.src_rdy and output_.dst_rdy:
                    output_.next_src_rdy = False
                else:
                    output_.q = operand_b
                    output_.next_src_rdy = True
                    wait = True
        elif instruction["op"] == "float_add":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ + floatb)
        elif instruction["op"] == "float_subtract":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ - floatb)
        elif instruction["op"] == "float_multiply":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ * floatb)
        elif instruction["op"] == "float_divide":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            try:
                result = float_to_bits(float_ / floatb)
            except ZeroDivisionError:
                result = float_to_bits(float("nan"))
        elif instruction["op"] == "long_float_add":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double + doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double + doubleb))
        elif instruction["op"] == "long_float_subtract":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double - doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double - doubleb))
        elif instruction["op"] == "long_float_multiply":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double * doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double * doubleb))
        elif instruction["op"] == "long_float_divide":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            try:
                self.a_hi = chips_c.high_word(double_to_bits(double / doubleb))
                self.a_lo = chips_c.low_word(double_to_bits(double / doubleb))
            except ZeroDivisionError:
                self.a_hi = chips_c.high_word(double_to_bits(float("nan")))
                self.a_lo = chips_c.low_word(double_to_bits(float("nan")))
        elif instruction["op"] == "long_float_file_write":
            long_word = chips_c.join_words(self.a_hi, self.a_lo)
            self.output_files[instruction["file_name"]].write(
                "%.16f\n" %
                bits_to_double(long_word))
        elif instruction["op"] == "long_file_write":
            long_word = chips_c.join_words(self.a_hi, self.a_lo)
            self.output_files[instruction["file_name"]].write(
                "%f\n" %
                long_word)
        elif instruction["op"] == "assert":
            if operand_a == 0:
                raise ChipsAssertionFail(
                    instruction["file"],
                    instruction["line"])
        elif instruction["op"] == "report":
            print "%d (report (int) at line: %s in file: %s)" % (
                to_32_signed(self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_report":
            print "%d (report (long) at line: %s in file: %s)" % (
                to_64_signed(chips_c.join_words(self.a_hi, self.a_lo)),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "float_report":
            print "%f (report (float) at line: %s in file: %s)" % (
                bits_to_float(self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_float_report":
            print "%s (report (double) at line: %s in file: %s)" % (

                bits_to_double(chips_c.join_words(self.a_hi, self.a_lo)),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "unsigned_report":
            print "%d (report (unsigned) at line: %s in file: %s)" % (
                self.a_lo,
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_unsigned_report":
            print "%d (report (unsigned long) at line: %s in file: %s)" % (
                chips_c.join_words(self.a_hi, self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "wait_clocks":
            if self.timer == operand_a:
                wait = False
                self.timer = 0
            else:
                wait = True
                self.timer += 1

        else:
            print "Unknown machine instruction", instruction["op"]
            sys.exit(-1)

        # Write data back
        if result is not None:
            self.registers[z] = result

        # manipulate stack pointer
        if wait:
            self.program_counter = this_instruction

        self.clock += 1