risc8asm.py 6.1 KB

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