Exemplo n.º 1
0
def push_pop(instructions):
    """substitue push and pop macros with real instructions"""

    new_instructions = []
    i = 0
    while i < len(instructions):
        instruction = instructions[i]
        trace = instruction["trace"]
        if i < len(instructions) - 1:
            next_instruction = instructions[i + 1]
        else:
            # dummy instruction
            next_instruction = {"op": None}

        if instruction["op"] == "push":
            # push
            new_instructions.append({
                "trace": trace,
                "op": "store",
                "literal": 0,
                "z": tos,
                "a": instruction["reg"],
                "comment": "push"
            })
            new_instructions.append({
                "trace": trace,
                "op": "addl",
                "z": tos,
                "a": tos,
                "literal": scaled_byte_addr(4)
            })
        elif instruction["op"] == "pop":
            # pop
            new_instructions.append({
                "trace": trace,
                "op": "addl",
                "z": tos,
                "a": tos,
                "literal": scaled_byte_addr(-4),
                "comment": "pop"
            })
            new_instructions.append({
                "trace": trace,
                "op": "load",
                "z": instruction["reg"],
                "a": tos
            })
        else:
            new_instructions.append(instruction)
        i += 1

    return new_instructions
Exemplo n.º 2
0
 def load_8(self, src_addr, is_signed):
     if scaled_byte_addr(4) != 4:
         raise Exception("cannot perform byte access")
     ret = self[src_addr]
     if is_signed and ret & 0x80 != 0:
         return ret | 0xffffff00
     return ret
Exemplo n.º 3
0
    def __getitem__(self, address):
        if address < 0 or address >= scaled_byte_addr(self.size_in_bytes):
            raise Exception("trying to access too large a memory address",
                    address)
#        if address not in self.dict:
#            raise Exception("trying to access uninitialized memory")
        return self.dict.get(address, 0)
Exemplo n.º 4
0
 def store_16(self, dest_addr, value):
     if scaled_byte_addr(4) != 4:
         raise Exception("cannot perform byte access")
     if dest_addr % 2 != 0:
         raise Exception("unaligned store16", operand_a)
     self[dest_addr] = (value >> 8) & 0xff
     self[dest_addr + 1] = value & 0xff
Exemplo n.º 5
0
 def load_16(self, operand_a, is_signed):
     if scaled_byte_addr(4) != 4:
         raise Exception("cannot perform byte access")
     if operand_a % 2 != 0:
         raise Exception("unaligned load16", operand_a)
     ret = (self[operand_a] << 8) | self[operand_a + 1]
     if is_signed and ret & 0x8000 != 0:
         return ret | 0xffff0000
     return ret
Exemplo n.º 6
0
 def store(self, operand_a, operand_b):
     if scaled_byte_addr(4) == 4:
         if operand_a % 4 != 0:
             raise Exception("unaligned store", operand_a)
         self[operand_a] = (operand_b >> 24) & 0xff
         self[operand_a + 1] = (operand_b >> 16) & 0xff
         self[operand_a + 2] = (operand_b >> 8) & 0xff
         self[operand_a + 3] = operand_b & 0xff
     else:
         self[operand_a] = operand_b
Exemplo n.º 7
0
 def load(self, operand_a):
     if scaled_byte_addr(4) == 4:
         if operand_a % 4 != 0:
             raise Exception("unaligned load", operand_a)
         result = self[operand_a]
         result = (result << 8) | self[operand_a + 1]
         result = (result << 8) | self[operand_a + 2]
         result = (result << 8) | self[operand_a + 3]
     else:
         result = self[operand_a]
     return result
Exemplo n.º 8
0
def store_object(trace, instructions, n, offset, local, leave_on_stack=False):
    """
    Store an item into the specified location

    if n = 1 the item is taken from the result register if n = 2 the item is
    taken from result and result_hi register if n > 2 the item is taken
    from the stack if local is true, the location is assumed to be relative
    to the frame register if offset is not specified, assume that address
    is in address if leave_on_stack is true the item is copied to the
    specified location, but left on the stack.  if the item was not on the
    stack in the first place, the value is left in the result registers
    either way.
    """
    if offset is not None:
        if local:
            instructions.append({
                "trace": trace,
                "op": "addl",
                "z": address,
                "a": frame,
                "literal": offset
            })
        else:
            instructions.append({
                "trace": trace,
                "op": "literal",
                "z": address,
                "literal": offset
            })
    if n == 1:
        instructions.append({
            "trace": trace,
            "op": "store",
            "literal": 0,
            "a": result,
            "z": address
        })
    elif n == 2:
        instructions.append({
            "trace": trace,
            "op": "store",
            "literal": 0,
            "a": result,
            "z": address
        })
        instructions.append({
            "trace": trace,
            "op": "addl",
            "z": address,
            "a": address,
            "literal": scaled_byte_addr(4)
        })
        instructions.append({
            "trace": trace,
            "op": "store",
            "literal": 0,
            "a": result_hi,
            "z": address
        })
    else:
        instructions.append({
            "trace": trace,
            "op": "addl",
            "z": address,
            "a": address,
            "literal": scaled_word_addr(n - 1)
        })
        if leave_on_stack:
            instructions.append({
                "trace": trace,
                "op": "addl",
                "z": tos_copy,
                "a": tos,
                "literal": 0
            })
            for i in range(n):
                instructions.append({
                    "trace": trace,
                    "op": "addl",
                    "z": tos_copy,
                    "a": tos_copy,
                    "literal": scaled_word_addr(-1)
                })
                instructions.append({
                    "trace": trace,
                    "op": "load",
                    "z": result,
                    "a": tos_copy
                })
                instructions.append({
                    "trace": trace,
                    "op": "store",
                    "literal": 0,
                    "a": result,
                    "z": address
                })
                if i < n - 1:
                    instructions.append({
                        "trace": trace,
                        "op": "addl",
                        "z": address,
                        "a": address,
                        "literal": scaled_word_addr(-1)
                    })
        else:
            for i in range(n):
                pop(trace, instructions, result)
                instructions.append({
                    "trace": trace,
                    "op": "store",
                    "literal": 0,
                    "a": result,
                    "z": address
                })
                if i < n - 1:
                    instructions.append({
                        "trace": trace,
                        "op": "addl",
                        "z": address,
                        "a": address,
                        "literal": scaled_word_addr(-1)
                    })
    return instructions
Exemplo n.º 9
0
 def store_8(self, dest_addr, value):
     if scaled_byte_addr(4) != 4:
         raise Exception("cannot perform byte access")
     self[dest_addr] = value & 0xff
Exemplo n.º 10
0
 def __setitem__(self, address, value):
     if address < 0 or address >= scaled_byte_addr(self.size_in_bytes):
         raise Exception("trying to access too large a memory address",
                 address)
     self.dict[address] = value