diff --git a/.gitignore b/.gitignore index 2ff2726..e652180 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ build deprc_setup.py __pycache__/ tests/dump/*.bin -tests/dump/*.txt \ No newline at end of file +tests/dump/*.txt +**/.DS_Store \ No newline at end of file diff --git a/src/riscv_assembler/data/instr_data.dat b/src/riscv_assembler/data/instr_data.dat index 7160191..35d37c5 100644 --- a/src/riscv_assembler/data/instr_data.dat +++ b/src/riscv_assembler/data/instr_data.dat @@ -29,6 +29,7 @@ sltiu 0010011 011 xori 0010011 100 slri 0010011 101 0000000 srai 0010011 101 0100000 +srli 0010011 101 0100000 ori 0010011 110 andi 0010011 111 addiw 0011011 000 diff --git a/src/riscv_assembler/instr_arr.py b/src/riscv_assembler/instr_arr.py index 587336d..a08d8c2 100644 --- a/src/riscv_assembler/instr_arr.py +++ b/src/riscv_assembler/instr_arr.py @@ -56,8 +56,12 @@ def compute_instr(self, instr, rs1, imm, rd): instr = super().check_instr_valid(instr, I_instr) opcode, f3 = 0, 1 + immediate = _I.immediate(imm) + if instr == "srai": + immediate = "0100000" + immediate[7:] + return "".join([ - _I.immediate(imm), + immediate, super().reg(rs1), instr_map[instr][f3], super().reg(rd), @@ -92,14 +96,18 @@ def compute_instr(self, instr, rs1, rs2, imm): @staticmethod def immediate(imm, n): - '''mod_imm = (int(imm) - ((int(imm) >> 12) << 12)) >> 5 # imm[11:5] - mod_imm_2 = int(imm) - ((int(imm) >> 5) << 5) # imm[4:0] - - return mod_imm, mod_imm_2''' - mod_imm = format(((1 << 12) - 1) & int(imm), '012b') + '''returns upper 7 bits of imm when n == 1 and lower 5 bits when n == 0''' + if not imm.isdigit(): + raise ValueError("Attempting to use string as imm for 'sw'") + + imm = int(imm) + + assert -2048 <= imm <= 2047, f"Immediate {imm} out of range for 'sw' (expected -2048 to 2047)" + + mod_imm = format(imm, '012b') if n == 1: - return mod_imm[0] + mod_imm[12-10 : 12-4] - return mod_imm[12-4 : 12 - 0] + mod_imm[1] + return mod_imm[0:7] + return mod_imm[7:12] class _SB(Instruction): @@ -181,19 +189,25 @@ def __call__(self, *args): @staticmethod def JUMP(tk : str, line_num : int, code: list) -> int: + if tk.isdigit(): + return int(tk) try: - index, skip_labels = code.index(tk + ":"), 0 + index, skip_lines = code.index(tk + ":"), 0 except: raise Exception('''Address not found for {}! Provided assembly code could be faulty, branch is expressed but not found in code.'''.format(tk)) pos = 1 if index > line_num: # forward search: - skip_labels = sum([1 for i in range(line_num, index) if code[i][-1] == ":"]) + skip_lines = sum( + [1 for i in range(line_num, index) if not code[i] or code[i][-1] == ":"] + ) else: # backwards search - skip_labels = -1 * sum([1 for i in range(index, line_num) if code[i][-1] == ":"]) + skip_lines = -1 * (sum( + [1 for i in range(index, line_num) if not code[i] or code[i][-1] == ":"] + ) + 1) # add one to jump to line below label, not above - return (index - line_num - skip_labels) * 4 * pos + return (index - line_num - skip_lines) * 4 * pos class _R_parse(InstructionParser): @@ -370,8 +384,8 @@ def instruction_map(): "ld", "lbu", "lhu", "lwu", "fence", "fence.i", "slli", "slti", "sltiu", - "xori", "slri", "srai", - "ori", "andi", "addiw", + "slri", "srai", "srli", + "ori", "andi", "addiw", "xori" "slliw", "srliw", "sraiw", "jalr", "ecall", "ebreak", "CSRRW", "CSRRS","CSRRC",