Exemplo n.º 1
0
class Command:
    def __init__(self,
                 program,
                 pos,
                 name=None,
                 first=None,
                 second=None,
                 third=None,
                 imm=None,
                 label=None):
        name = name.lower()
        if name not in rType.keys() and \
           name not in iType.keys() and \
           name not in jType.keys():
            raise "'%s' is not a MIPS assembly command." % (name.lower())
        self.program = program
        self.pos = pos
        self.name = name

        self.rs = EmptyRegister()
        self.rt = EmptyRegister()
        self.rd = EmptyRegister()

        registers = (
          rType[name][-1] if name in rType else \
          iType[name][-1] if name in iType else \
          jType[name][-1]
        )

        rList = [x for x in [first, second, third] if x is not None]

        if len(registers) != len(rList):
            raise "'%s' requires %d registers." % (name, len(registers))

        for _, reg in zip(registers, rList):
            if _ == "rs":
                self.rs = Register(reg)
            if _ == "rd":
                self.rd = Register(reg)
            if _ == "rt":
                self.rt = Register(reg)

        if isinstance(imm, int):
            self.imm = imm
        else:
            self.imm = eval(imm) if imm is not None else 0
        self.label = label

        if imm is not None and self.label is not None:
            raise "Label and imm can't both exist."

    @staticmethod
    def parseLine(program, pos, line):
        global commandTypes
        for m in commandTypes:
            ans = m.match(line)
            if ans is not None:
                group = ans.groupdict()
                return Command(program=program, pos=pos, **group)
        raise "'%s' is not a command." % (line)

    def toBin(self):
        if self.name in rType.keys():
            ans = 0  # opcode
            ans |= (self.rs.binary() << 21)  # rs
            ans |= (self.rt.binary() << 16)  # rt
            ans |= (self.rd.binary() << 11)  # rd
            ans |= (self.imm << 6)  # shamt
            ans |= (rType[self.name][1] << 0)  # funct
            return ans

        if self.name in iType.keys():
            ans = iType[self.name][0] << 26  # opcode
            ans |= (self.rs.binary() << 21)  # rs
            ans |= (self.rt.binary() << 16)  # rt
            if len(iType[self.name]) > 2:
                ans |= (iType[self.name][1] << 16)  # rt adjustment

            if self.label is not None:
                if "b" == self.name[0]:
                    tmp = self.program.Label(self.label) - self.pos - 1
                else:
                    tmp = self.program.Label(self.label)
                ans |= (tmp & 0xFFFF)
            else:
                if "b" == self.name[0]:
                    ans |= (self.imm >> 2 & 0xFFFF)
                else:
                    ans |= (self.imm & 0xFFFF)
            return ans

        if self.name in jType.keys():
            ans = jType[self.name][0] << 26  # opcode
            if self.label is not None:
                ans |= ((self.program.Label(self.label) + \
                       self.program.textBase) % (1 << 26))  # label
            else:
                ans |= (self.imm % (1 << 26))  # address
            return ans

    def Size(self):
        return 1

    def Bytes(self):
        x = self.toBin()
        ans = [x >> 24, x >> 16 & 0xFF, x >> 8 & 0xFF, x & 0xFF]
        return ans

    def __repr__(self):
        return "Command(%s, %s, %s, %s, %s, %s)" % \
          (self.name, self.rs, self.rt, self.rd, self.imm, self.label)
Exemplo n.º 2
0
class Command:
  def __init__(self, program, pos, name = None, first = None, 
              second = None, third = None, imm = None, label = None):
    name = name.lower()
    if name not in rType.keys() and \
       name not in iType.keys() and \
       name not in jType.keys():
      raise "'%s' is not a MIPS assembly command." % (name.lower())
    self.program = program
    self.pos = pos
    self.name = name
    
    self.rs = EmptyRegister()
    self.rt = EmptyRegister()
    self.rd = EmptyRegister()
    
    registers = (
      rType[name][-1] if name in rType else \
      iType[name][-1] if name in iType else \
      jType[name][-1]
    )
    
    rList = [x for x in [first, second, third] if x is not None]
    
    if len(registers) != len(rList):
      raise "'%s' requires %d registers." % (name, len(registers))
    
    for _, reg in zip(registers, rList):
      if _ == "rs":
        self.rs = Register(reg)
      if _ == "rd":
        self.rd = Register(reg)
      if _ == "rt":
        self.rt = Register(reg)  
      
    if isinstance(imm, int):
      self.imm = imm
    else:
      self.imm = eval(imm) if imm is not None else 0
    self.label = label
    
    if imm is not None and self.label is not None:
      raise "Label and imm can't both exist."
      
      
  @staticmethod
  def parseLine(program, pos, line):
    global commandTypes
    for m in commandTypes:
      ans = m.match(line)
      if ans is not None:
        group = ans.groupdict()
        return Command(program = program, pos = pos, **group)
    raise "'%s' is not a command." % (line)
    
  def toBin(self):
    if self.name in rType.keys():
      ans = 0                           # opcode
      ans |= (self.rs.binary() << 21)   # rs
      ans |= (self.rt.binary() << 16)   # rt
      ans |= (self.rd.binary() << 11)   # rd
      ans |= (self.imm << 6)            # shamt
      ans |= (rType[self.name][1] << 0) # funct
      return ans
      
    if self.name in iType.keys():
      ans = iType[self.name][0] << 26   # opcode
      ans |= (self.rs.binary() << 21)   # rs
      ans |= (self.rt.binary() << 16)   # rt
      if len(iType[self.name]) > 2:
        ans |= (iType[self.name][1] << 16) # rt adjustment
        
      if self.label is not None:
        if "b" == self.name[0]:
          tmp = self.program.Label(self.label) - self.pos - 1
        else:
          tmp = self.program.Label(self.label)
        ans |= (tmp & 0xFFFF)
      else:
        if "b" == self.name[0]:
          ans |= (self.imm >> 2 & 0xFFFF)
        else:
          ans |= (self.imm & 0xFFFF)
      return ans
      
    if self.name in jType.keys():
      ans = jType[self.name][0] << 26   # opcode
      if self.label is not None:
        ans |= ((self.program.Label(self.label) + \
               self.program.textBase) % (1 << 26))  # label
      else:
        ans |= (self.imm % (1 << 26)) # address
      return ans
      
  def Size(self):
    return 1
    
  def Bytes(self):
    x = self.toBin()
    ans = [
      x >> 24,
      x >> 16 & 0xFF,
      x >> 8 & 0xFF,
      x & 0xFF
    ]
    return ans
    
  def __repr__(self):
    return "Command(%s, %s, %s, %s, %s, %s)" % \
      (self.name, self.rs, self.rt, self.rd, self.imm, self.label)
Exemplo n.º 3
0
class Instruction:
    def __init__(self,
                 program,
                 position,
                 name=None,
                 first=None,
                 second=None,
                 third=None,
                 imm=None,
                 label=None,
                 immb=None):

        name = name.lower()
        #if imm is not None:
        #print(imm)
        #if label is not None:
        #print(label)
        if name not in r_type.keys() and \
           name not in i_type.keys() and \
           name not in s_type.keys() and \
           name not in j_type.keys() and \
           name not in interrupt_type.keys():
            raise Exception("'%s' is not a MIPS opcode" % (name.lower()))

        self.program = program
        self.position = position
        self.name = name

        self.rs = UnusedRegister()
        self.rt = UnusedRegister()
        self.rd = UnusedRegister()

        # Verify that the right registers are present
        registers = (r_type[name][-1] if name in r_type else \
                     s_type[name][-1] if name in s_type else \
                     i_type[name][-1] if name in i_type else \
                     j_type[name][-1] if name in j_type else \
                     interrupt_type[name][-1])
        rlist = [x for x in [first, second, third] if x is not None]

        if len(registers) == 3 and (first is None or second is None \
            or third is None):
            raise Exception("'%s' requires three registers" % (name))
        if len(registers) == 2 and (first is None or second is None \
            or third is not None):
            raise Exception("'%s' requires two registers" % (name))
        if len(registers) == 1 and (first is None or second is not None \
            or third is not None):
            raise Exception("'%s' requires one register" % (name))
        if len(registers) == 0 and (first is not None or second is not None \
            or third is not None):
            raise Exception("'%s' requires no registers" % (name))

        for pos, reg in zip(registers, rlist):
            if pos == "rs": self.rs = Register(reg)
            if pos == "rd": self.rd = Register(reg)
            if pos == "rt": self.rt = Register(reg)

        if isinstance(imm, int):
            self.imm = imm
        else:
            self.imm = eval(imm) if imm is not None else 0
        if isinstance(immb, int):
            self.immb = immb
        else:
            self.immb = eval(immb) if immb is not None else 0
        self.label = label

        if imm is not None and self.label is not None:
            raise Exception("A label and an immediate. Confused.")

    @staticmethod
    def parseline(program, position, line):
        global instruction_types
        for t in instruction_types:
            m = t.match(line)
            if m is not None:
                g = m.groupdict()
                if 'name' in g and \
                    g['name'].lower() in supported_pseudoinstructions:
                    return PseudoInstruction(program, position,
                                             **m.groupdict())

                return Instruction(program=program, position=position, **g)
        print line
        raise Exception("'%s' not an instruction" % (line))

    def ToBinary(self):
        if self.name in r_type.keys():
            b = (r_type[self.name][0] << 26)  # opcode
            b |= (self.rs.binary() << 21)  # rs
            b |= (self.rt.binary() << 16)  # rt
            b |= (self.rd.binary() << 11)  # rd

            #b |= (self.imm << 6)             # shamt
            b |= (r_type[self.name][1] << 0)  # funct
            return b

        if self.name in i_type.keys():
            b = i_type[self.name][0] << 26  # opcode
            #if "jr" == self.name[0]:
            #print self.rs.binary()
            b |= (self.rs.binary() << 21)  # rs
            b |= (self.rt.binary() << 16)  # rt
            if self.label is not None:
                if "b" == self.name[0]:
                    #print "branch"
                    #print self.program.Label(self.label)
                    #print self.position
                    z = (self.program.Label(self.label) - self.position -
                         1) * 4
                else:
                    z = self.program.Label(self.label)
                b |= (z & 0xFFFF)  # label
            else:
                b |= (self.imm & 0xFFFF)  # imm

            return b

        if self.name in j_type.keys():
            b = (j_type[self.name][0]) << 26  #opcode
            if self.label is not None:
                b |= (self.program.Label(
                    self.label)) * 4 + self.program.text_base
            else:
                b |= (self.imm & 0x03FFFFFF)  # address
            return b

        if self.name in s_type.keys():
            b = (s_type[self.name][0]
                 ) << 26  #opcode                           # opcode
            b |= (self.rs.binary() << 21)  # rs
            b |= (self.rt.binary() << 16)  # rt
            b |= (self.imm << 12)  # spu reg
            b |= (s_type_op[self.name] << 8)  # opcode cont.
            b |= (self.immb)  #delim
            return b

        if self.name in interrupt_type.keys():
            b = (interrupt_type[self.name][0]) << 26
            b |= self.imm
            return b

    # The size, in words, of this instruction
    def Size(self):
        return 1

    def Bytes(self, endian="big"):
        b = self.ToBinary()
        bytes = [b >> 24, b >> 16 & 0xFF, b >> 8 & 0xFF, b & 0xFF]
        return bytes[::-1] if endian.lower() == "little" else bytes

    def __repr__(self):
        return "Instruction(%s, %s, %s, %s, %s, %s)"% \
           (self.name, self.rs, self.rt, self.rd, self.imm, self.label)