Skip to content

Instantly share code, notes, and snippets.

@ldct
Created October 24, 2015 21:11
Show Gist options
  • Save ldct/721da9f00b6d89bd0265 to your computer and use it in GitHub Desktop.
Save ldct/721da9f00b6d89bd0265 to your computer and use it in GitHub Desktop.
def decode_execute(instruction):
d, s, t = (instruction >> 11) & 0b11111, (instruction >> 21) & 0b11111, (instruction >> 16) & 0b11111
i = instruction & 0b1111111111111111
if i & 0x8000: i -= 0x10000 # make sure we interpret the value as a signed 16 bit integer
if instruction & 0b11111100000000000000011111111111 == 0b00000000000000000000000000100000: # add (add)
return "add $%d $%d $%d" % (d, s, t)
elif instruction & 0b11111100000000000000011111111111 == 0b00000000000000000000000000100010: # subtract (sub)
return "sub $%d $%d $%d" % (d, s, t)
elif instruction & 0b11111100000000001111111111111111 == 0b00000000000000000000000000011000: # multiply (mult)
return ("mult ${}, ${}".format(s, t), "${}={}, ${}={}".format(s, r[s], t, r[t]))
elif instruction & 0b11111100000000001111111111111111 == 0b00000000000000000000000000011001: # multiply unsigned (multu)
return ("multu ${}, ${}".format(s, t), "${}={}, ${}={}".format(s, r[s], t, r[t]))
elif instruction & 0b11111100000000001111111111111111 == 0b00000000000000000000000000011010: # divide (div)
return ("div ${}, ${}".format(s, t), "${}={}, ${}={}".format(s, r[s], t, r[t]))
elif instruction & 0b11111100000000001111111111111111 == 0b00000000000000000000000000011011: # divide unsigned (divu)
return ("divu ${}, ${}".format(s, t), "${}={}, ${}={}".format(s, r[s], t, r[t]))
elif instruction & 0b11111111111111110000011111111111 == 0b00000000000000000000000000010000: # move from high/remainder (mfhi)
return ("mfhi ${}".format(d), "${}={}".format(d, r[d]))
elif instruction & 0b11111111111111110000011111111111 == 0b00000000000000000000000000010010: # move from low/quotient (mflo)
return ("mflo ${}".format(d), "${}={}".format(d, r[d]))
elif instruction & 0b11111111111111110000011111111111 == 0b00000000000000000000000000010100: # load immediate and skip (lis)
return ("lis $%d" % (d))
elif instruction & 0b11111100000000000000000000000000 == 0b10001100000000000000000000000000: # load word (lw)
return "lw $%d, %d($%d)" % (t, i, s)
elif instruction & 0b11111100000000000000000000000000 == 0b10101100000000000000000000000000: # store word (sw)
return "sw $%d, %d($%d)" % (t, i, s)
elif instruction & 0b11111100000000000000011111111111 == 0b00000000000000000000000000101010: # set less than (slt)
return "slt $%d $%d $%d" % (d, s, t)
elif instruction & 0b11111100000000000000011111111111 == 0b00000000000000000000000000101011: # set less than unsigned (sltu)
return ("sltu ${}, ${}, ${}".format(d, s, t), "${}={}, ${}={}, ${}={}".format(d, r[d], s, r[s], t, r[t]))
elif instruction & 0b11111100000000000000000000000000 == 0b00010000000000000000000000000000: # branch on equal (beq)
return "beq $%d $%d %d" % (s, t, i)
elif instruction & 0b11111100000000000000000000000000 == 0b00010100000000000000000000000000: # branch on not equal (bne)
return "bne $%d $%d %d" % (s, t, i)
elif instruction & 0b11111100000111111111111111111111 == 0b00000000000000000000000000001000: # jump register (jr)
if s == 0:
return inst # hackety hack: jr $0 = 8
else:
return "jr $%d" % s
elif instruction & 0b11111100000111111111111111111111 == 0b00000000000000000000000000001001: # jump and link register (jalr)
if s == 0:
return inst # hackety hack
else:
return "jalr $%d" % s
else:
return instruction
def decode_str(s):
s = s.split(",")
return [int(x, 2) for x in s]
# for inst in decode_str("0b00000000000000000010000000010100, 0b00000000000000000000000000001000, 0b00000011110001001111000000100010, 0b00000011110000000011000000100000, 0b00000000000000000010000000010100, 0b00000000000000000000000000001000, 0b10101100110001000000000000000000, 0b00000000000000000001100000010100, 0b00000000000000000000000000000101, 0b00000000000000110010000000100000, 0b00000000000000000001100000010100, 0b00000000000000000000000000000110, 0b00000000100000110010000000101010, 0b00010000100000000000000000000011, 0b00010100011000000000000000000010, 0b00000000000000000001100000010100, 0b00000000000000000000001111111111, 0b00000000000000000001100000010100, 0b00000000000000000000000000000111, 0b00000000000000110010000000100000, 0b00000000000000000001100000010100, 0b00000000000000000000000000001000, 0b00010000100000110000000000000100, 0b00000000100000110010000000101010, 0b00010000100000000000000000000010, 0b00010100011000000000000000000001, 0b00000000000000000001100000010100, 0b00000000000000000000000000001001, 0b00000000000000000001100000010100, 0b00000000000000000000000000001010, 0b00000000000000110010000000100000, 0b00000000000000000001100000010100, 0b00000000000000000000000000001011, 0b00010000100000110000000000000011, 0b00000000100000110010000000101010, 0b00010000100000000000000000000001, 0b00010100011000000000000000000000, 0b00000000000000000001100000010100, 0b00000000000000000000000000001100, 0b00000000000000000001100000010100, 0b00000000000000000000000000001101, 0b10001111110001000000000000000000, 0b00000011110001001111000000100000, 0b00000011111000000000000000001000"):
for i, inst in enumerate(decode_str("00000000000000000010000000010100, 00000000000000000000000000001000, 00000011110001001111000000100010, 00000011110000000011000000100000, 00000000000000000010000000010100, 00000000000000000000000000001000, 10101100110001000000000000000000, 00010000000000000000000000000011, 00000000000111110010100000100000, 00000000000111110010100000100000, 00000011111000000000000000001000, 00010000000000001111111111111011, 10001111110001000000000000000000, 00000011110001001111000000100000, 00000011111000000000000000001000")):
print('{0: >2} {1}'.format(i, decode_execute(inst)))
# print(str(i).zfill(2), decode_execute(inst))%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment