risc8asm.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import argparse
  2. import sys
  3. import math
  4. from os import path
  5. import asm_compiler as compiler
  6. asmc = compiler.Compiler(byte_order='big')
  7. asmc.add_reg('r0', 0)
  8. asmc.add_reg('r1', 1)
  9. asmc.add_reg('r2', 2)
  10. asmc.add_reg('r3', 3)
  11. class MoveInstr(compiler.Instruction):
  12. def get_imm_operands(self, operands):
  13. try:
  14. self.compiler.decode_reg(operands[1])
  15. return 1
  16. except compiler.CompilingError:
  17. return 2
  18. def compile(self, operands):
  19. regs = [0, 0]
  20. imm = []
  21. regs[0] = self.compiler.decode_reg(operands[0])
  22. try:
  23. regs[1] = self.compiler.decode_reg(operands[1])
  24. self.imm_operands = 0 # Assuming this gonna be changed every time
  25. except compiler.CompilingError:
  26. regs[1] = regs[0]
  27. self.imm_operands = 1
  28. imm = [self.compiler.decode_bytes(operands[1])]
  29. instr = self._gen_instr(regs, imm)
  30. return [instr] + imm
  31. asmc.add_instr(MoveInstr('MOVE ', 'b0000_????'))
  32. asmc.add_instr(compiler.Instruction('ADD ', 'b0001_????'))
  33. asmc.add_instr(compiler.Instruction('SUB ', 'b0010_????'))
  34. asmc.add_instr(compiler.Instruction('AND ', 'b0011_????'))
  35. asmc.add_instr(compiler.Instruction('OR ', 'b0100_????'))
  36. asmc.add_instr(compiler.Instruction('XOR ', 'b0101_????'))
  37. asmc.add_instr(compiler.Instruction('MUL ', 'b0110_????'))
  38. asmc.add_instr(compiler.Instruction('DIV ', 'b0111_????'))
  39. asmc.add_instr(compiler.Instruction('BR ', 'b1000_????', 2))
  40. asmc.add_instr(compiler.Instruction('SLL ', 'b1001_??00'))
  41. asmc.add_instr(compiler.Instruction('SRL ', 'b1001_??01'))
  42. asmc.add_instr(compiler.Instruction('SRA ', 'b1001_??10'))
  43. asmc.add_instr(compiler.Instruction('SRAS ', 'b1001_??11'))
  44. asmc.add_instr(compiler.Instruction('LWHI ', 'b1010_??00', 3))
  45. asmc.add_instr(compiler.Instruction('SWHI ', 'b1010_??01'))
  46. asmc.add_instr(compiler.Instruction('LWLO ', 'b1010_??10', 3))
  47. asmc.add_instr(compiler.Instruction('SWLO ', 'b1010_??11', 3))
  48. asmc.add_instr(compiler.Instruction('INC ', 'b1011_??00'))
  49. asmc.add_instr(compiler.Instruction('DEC ', 'b1011_??01'))
  50. asmc.add_instr(compiler.Instruction('GETAH', 'b1011_??10'))
  51. asmc.add_instr(compiler.Instruction('GETIF', 'b1011_??11'))
  52. asmc.add_instr(compiler.Instruction('PUSH ', 'b1100_??00'))
  53. asmc.add_instr(compiler.Instruction('POP ', 'b1100_??01'))
  54. asmc.add_instr(compiler.Instruction('COM ', 'b1100_??10', 1))
  55. asmc.add_instr(compiler.Instruction('SETI ', 'b1100_??11'))
  56. asmc.add_instr(compiler.Instruction('BEQ ', 'b1101_??00', 3))
  57. asmc.add_instr(compiler.Instruction('BGT ', 'b1101_??01', 3))
  58. asmc.add_instr(compiler.Instruction('BGE ', 'b1101_??10', 3))
  59. asmc.add_instr(compiler.Instruction('BZ ', 'b1101_0011'))
  60. asmc.add_instr(compiler.Instruction('CALL ', 'b1111_0000', 2))
  61. asmc.add_instr(compiler.Instruction('RET ', 'b1111_0001'))
  62. asmc.add_instr(compiler.Instruction('JUMP ', 'b1111_0010', 2))
  63. asmc.add_instr(compiler.Instruction('RETI ', 'b1111_0011'))
  64. asmc.add_instr(compiler.Instruction('CLC ', 'b1111_0100'))
  65. asmc.add_instr(compiler.Instruction('SETC ', 'b1111_0101'))
  66. asmc.add_instr(compiler.Instruction('CLS ', 'b1111_0110'))
  67. asmc.add_instr(compiler.Instruction('SETS ', 'b1111_0111'))
  68. asmc.add_instr(compiler.Instruction('SSETS', 'b1111_1000'))
  69. asmc.add_instr(compiler.Instruction('CLN ', 'b1111_1001'))
  70. asmc.add_instr(compiler.Instruction('SETN ', 'b1111_1010'))
  71. asmc.add_instr(compiler.Instruction('SSETN', 'b1111_1011'))
  72. asmc.add_instr(compiler.Instruction('RJUMP', 'b1111_1100', 2))
  73. asmc.add_instr(compiler.Instruction('RBWI ', 'b1111_1101'))
  74. if __name__ == '__main__':
  75. parser = argparse.ArgumentParser(description='Assembly compiler', add_help=True)
  76. parser.add_argument('file', help='Files to compile')
  77. parser.add_argument('-t', '--output_type', choices=['bin', 'mem', 'binary', 'mif'], default='mem', help='Output type')
  78. parser.add_argument('-S', '--slice', type=int, default=0, help='if defined, output to multiple sliced files')
  79. parser.add_argument('-o', '--output', help='Output file')
  80. parser.add_argument('-f', '--force', action='store_true', help='Force override output file')
  81. parser.add_argument('-s', '--stdout', action='store_true', help='Print to stdout')
  82. parser.add_argument('-l', '--size', type=int, default=0, help='if defined, fill rest of memory with 0x00')
  83. args = parser.parse_args(sys.argv[1:])
  84. if not path.isfile(args.file):
  85. print(f'No file {args.file}!')
  86. sys.exit(1)
  87. output = args.output
  88. if not output:
  89. bname = args.file.rsplit('.', 1)
  90. if args.output_type == 'mem':
  91. ext = '.mem'
  92. elif args.output_type == 'bin':
  93. ext = '.bin'
  94. elif args.output_type == 'mif':
  95. ext = '.mif'
  96. else:
  97. ext = '.out'
  98. output = bname[0] + ext
  99. outputs = []
  100. sformat = f'01d'
  101. if args.slice > 0:
  102. sformat = f'0{int(math.log10(args.slice)) + 1}d'
  103. for i in range(0, args.slice):
  104. bname = output.rsplit('.', 1)
  105. outputs.append(f'{bname[0]}_{format(i, sformat)}.{bname[1]}')
  106. else:
  107. outputs = [output]
  108. if not args.stdout and not args.force:
  109. for output in outputs:
  110. if path.isfile(output):
  111. print(f'Output file already exists {output}!')
  112. sys.exit(1)
  113. with open(args.file, 'r') as f:
  114. data = asmc.compile(args.file, f.readlines())
  115. if data is not None:
  116. if args.size > 0:
  117. data = data + (args.size - len(data)) * bytearray(b'\x00')
  118. for i, output in enumerate(outputs):
  119. y = data[i::len(outputs)]
  120. if args.output_type == 'binary':
  121. x = compiler.convert_to_binary(y)
  122. elif args.output_type == 'mem':
  123. x = compiler.convert_to_mem(y)
  124. elif args.output_type == 'mif':
  125. x = compiler.convert_to_mif(y, depth=len(y))
  126. else:
  127. x = bytes(y)
  128. op = 'Printing' if args.stdout else 'Saving'
  129. print(f"{op} {args.output_type} data '{output}' [Size: {len(y)}B Slice: {format(i + 1, sformat)}/{len(outputs)}]")
  130. if args.stdout:
  131. print(x.decode())
  132. else:
  133. with open(output, 'wb') as of:
  134. of.write(x)
  135. print(f"Total program size: {len(data)}B")
  136. else:
  137. print(f'Failed to compile {args.file}!')
  138. sys.exit(1)
  139. sys.exit(0)