diff --git a/src/riscv_assembler/data/instr_data.dat b/src/riscv_assembler/data/instr_data.dat index 7160191..90c0f1d 100644 --- a/src/riscv_assembler/data/instr_data.dat +++ b/src/riscv_assembler/data/instr_data.dat @@ -27,7 +27,7 @@ slli 0010011 001 0000000 slti 0010011 010 sltiu 0010011 011 xori 0010011 100 -slri 0010011 101 0000000 +srli 0010011 101 0000000 srai 0010011 101 0100000 ori 0010011 110 andi 0010011 111 @@ -58,10 +58,95 @@ auipc 0010111 -1 -1 lui 0110111 -1 -1 jal 1101111 -1 -1 mul 0110011 000 0000001 +mulw 0111011 000 0000001 mulh 0110011 001 0000001 -mulsu 0110011 010 0000001 -mulu 0110011 011 0000001 +mulhsu 0110011 010 0000001 +mulhu 0110011 011 0000001 div 0110011 100 0000001 +divw 0111011 100 0000001 divu 0110011 101 0000001 +divuw 0111011 101 0000001 rem 0110011 110 0000001 -remu 0110011 111 0000001 \ No newline at end of file +remw 0111011 110 0000001 +remu 0110011 111 0000001 +remuw 0111011 111 0000001 +amoadd.d 0101111 011 0000000 +amoadd.w 0101111 010 0000000 +amoand.d 0101111 011 0110000 +amoand.w 0101111 010 0110000 +amomax.d 0101111 011 1010000 +amomax.w 0101111 010 1010000 +amomaxu.d 0101111 011 1110000 +amomaxu.w 0101111 010 1110000 +amomin.d 0101111 011 1000000 +amomin.w 0101111 010 1000000 +amominu.d 0101111 011 1100000 +amominu.w 0101111 010 1100000 +amoor.d 0101111 011 0100000 +amoor.w 0101111 010 0100000 +amoswap.d 0101111 011 0000100 +amoswap.w 0101111 010 0000100 +amoxor.d 0101111 011 0010000 +amoxor.w 0101111 010 0010000 +fmv.x.d 1010011 000 1110001 +fmv.x.w 1010011 000 1110000 +fmv.w.x 1010011 000 1111000 +fmv.d.x 1010011 000 1111001 +fadd.s 1010011 111 0000000 +fsub.s 1010011 111 0000100 +fmul.s 1010011 111 0001000 +fdiv.s 1010011 111 0001100 +feq.s 1010011 010 1010000 +fadd.d 1010011 111 0000001 +fsub.d 1010011 111 0000101 +fmul.d 1010011 111 0001001 +fdiv.d 1010011 111 0001101 +feq.d 1010011 010 1010001 +fsqrt.s 1010011 111 0101100 +fsqrt.d 1010011 111 0101101 +fmin.s 1010011 000 0010100 +fmax.s 1010011 001 0010100 +fmin.d 1010011 000 0010101 +fmax.d 1010011 001 0010101 +fmadd.s 1000011 111 +fnmadd.s 1001111 111 +fmsub.s 1000111 111 +fnmsub.s 1001011 111 +fmadd.d 1000011 111 +fnmadd.d 1001111 111 +fmsub.d 1000111 111 +fnmsub.d 1001011 111 +fclass.s 1010011 001 1110000 +fclass.d 1010011 001 1110001 +fle.s 1010011 000 1010000 +fle.d 1010011 000 1010001 +flt.s 1010011 001 1010000 +flt.d 1010011 001 1010001 +fcvt.s.wu 1010011 111 1101000 +fcvt.s.w 1010011 111 1101000 +fcvt.s.l 1010011 111 1101000 +fcvt.s.lu 1010011 111 1101000 +fcvt.d.wu 1010011 111 1101001 +fcvt.d.w 1010011 111 1101001 +fcvt.d.l 1010011 111 1101001 +fcvt.d.lu 1010011 111 1101001 +fcvt.w.s 1010011 001 1100000 +fcvt.wu.s 1010011 001 1100000 +fcvt.l.s 1010011 001 1100000 +fcvt.lu.s 1010011 001 1100000 +fcvt.w.d 1010011 001 1100001 +fcvt.wu.d 1010011 001 1100001 +fcvt.l.d 1010011 001 1100001 +fcvt.lu.d 1010011 001 1100001 +fcvt.s.d 1010011 111 0100000 +fcvt.d.s 1010011 111 0100001 +flw 0000111 010 +fld 0000111 011 +fsw 0100111 010 +fsd 0100111 011 +fsgnj.s 1010011 000 0010000 +fsgnjn.s 1010011 001 0010000 +fsgnjx.s 1010011 010 0010000 +fsgnj.d 1010011 000 0010001 +fsgnjn.d 1010011 001 0010001 +fsgnjx.d 1010011 010 0010001 \ No newline at end of file diff --git a/src/riscv_assembler/data/reg_map.dat b/src/riscv_assembler/data/reg_map.dat index 0b0e0dd..eedc002 100644 --- a/src/riscv_assembler/data/reg_map.dat +++ b/src/riscv_assembler/data/reg_map.dat @@ -1,64 +1,128 @@ -x0 x0 -x1 x1 -x2 x2 -x3 x3 -x4 x4 -x5 x5 -x6 x6 -x7 x7 -x8 x8 -x9 x9 -x10 x10 -x11 x11 -x12 x12 -x13 x13 -x14 x14 -x15 x15 -x16 x16 -x17 x17 -x18 x18 -x19 x19 -x20 x20 -x21 x21 -x22 x22 -x23 x23 -x24 x24 -x25 x25 -x26 x26 -x27 x27 -x28 x28 -x29 x29 -x30 x30 -x31 x31 -ra x1 -sp x2 -gp x3 -tp x4 -t0 x5 -t1 x6 -t2 x7 -s0 x8 -fp x8 -s1 x9 -a0 x10 -a1 x11 -a2 x12 -a3 x13 -a4 x14 -a5 x15 -a6 x16 -a7 x17 -s2 x18 -s3 x19 -s4 x20 -s5 x21 -s6 x22 -s7 x23 -s8 x24 -s9 x25 -s10 x26 -s11 x27 -t3 x28 -t4 x29 -t5 x30 -t6 x31 \ No newline at end of file +x0 x0 +x1 x1 +x2 x2 +x3 x3 +x4 x4 +x5 x5 +x6 x6 +x7 x7 +x8 x8 +x9 x9 +x10 x10 +x11 x11 +x12 x12 +x13 x13 +x14 x14 +x15 x15 +x16 x16 +x17 x17 +x18 x18 +x19 x19 +x20 x20 +x21 x21 +x22 x22 +x23 x23 +x24 x24 +x25 x25 +x26 x26 +x27 x27 +x28 x28 +x29 x29 +x30 x30 +x31 x31 +ra x1 +sp x2 +gp x3 +tp x4 +t0 x5 +t1 x6 +t2 x7 +s0 x8 +fp x8 +s1 x9 +a0 x10 +a1 x11 +a2 x12 +a3 x13 +a4 x14 +a5 x15 +a6 x16 +a7 x17 +s2 x18 +s3 x19 +s4 x20 +s5 x21 +s6 x22 +s7 x23 +s8 x24 +s9 x25 +s10 x26 +s11 x27 +t3 x28 +t4 x29 +t5 x30 +t6 x31 +f0 f0 +f1 f1 +f2 f2 +f3 f3 +f4 f4 +f5 f5 +f6 f6 +f7 f7 +f8 f8 +f9 f9 +f10 f10 +f11 f11 +f12 f12 +f13 f13 +f14 f14 +f15 f15 +f16 f16 +f17 f17 +f18 f18 +f19 f19 +f20 f20 +f21 f21 +f22 f22 +f23 f23 +f24 f24 +f25 f25 +f26 f26 +f27 f27 +f28 f28 +f29 f29 +f30 f30 +f31 f31 +ft0 f0 +ft1 f1 +ft2 f2 +ft3 f3 +ft4 f4 +ft5 f5 +ft6 f6 +ft7 f7 +fs0 f8 +fs1 f9 +fa0 f10 +fa1 f11 +fa2 f12 +fa3 f13 +fa4 f14 +fa5 f15 +fa6 f16 +fa7 f17 +fs2 f18 +fs3 f19 +fs4 f20 +fs5 f21 +fs6 f22 +fs7 f23 +fs8 f24 +fs9 f25 +fs10 f26 +fs11 f27 +ft8 f28 +ft9 f29 +ft10 f30 +ft11 f31 \ No newline at end of file diff --git a/src/riscv_assembler/instr_arr.py b/src/riscv_assembler/instr_arr.py index 587336d..2747f88 100644 --- a/src/riscv_assembler/instr_arr.py +++ b/src/riscv_assembler/instr_arr.py @@ -35,7 +35,6 @@ def __str__(self): def compute_instr(self, instr, rs1, rs2, rd): instr = super().check_instr_valid(instr, R_instr) opcode, f3, f7 = 0, 1, 2 - return "".join([ instr_map[instr][f7], super().reg(rs2), @@ -45,6 +44,30 @@ def compute_instr(self, instr, rs1, rs2, rd): instr_map[instr][opcode] ]) +class _R4(Instruction): + def __repr__(self): + return "R instruction" + + def __str__(self): + return "R instruction" + + def compute_instr(self, instr, rs3,rs2, rs1, rd): + instr = super().check_instr_valid(instr, R_instr) + + opcode, f3 = 0, 1, + if instr in ["fmadd.s","fnmadd.s","fmsub.s","fnmsub.s"]: + fmt="00" + elif instr in ["fmadd.d","fnmadd.d","fmsub.d","fnmsub.d"]: + fmt="01" + return "".join([ + super().reg(rs3)+fmt, + super().reg(rs2), + super().reg(rs1), + instr_map[instr][f3], + super().reg(rd), + instr_map[instr][opcode] + ]) + class _I(Instruction): def __repr__(self): return "I instruction" @@ -54,7 +77,17 @@ def __str__(self): def compute_instr(self, instr, rs1, imm, rd): instr = super().check_instr_valid(instr, I_instr) - opcode, f3 = 0, 1 + opcode, f3, f7 = 0, 1, 2 + if len(instr_map[instr])==3: + imm=format(((1 << 12) - 1) & int(imm), '05b') + return "".join([ + instr_map[instr][f7], + imm, + super().reg(rs1), + instr_map[instr][f3], + super().reg(rd), + instr_map[instr][opcode] + ]) return "".join([ _I.immediate(imm), @@ -80,7 +113,6 @@ def __str__(self): def compute_instr(self, instr, rs1, rs2, imm): instr = super().check_instr_valid(instr, S_instr) opcode, f3 = 0, 1 - return "".join([ _S.immediate(imm, 1), super().reg(rs2), @@ -97,9 +129,10 @@ def immediate(imm, n): return mod_imm, mod_imm_2''' mod_imm = format(((1 << 12) - 1) & int(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): @@ -146,9 +179,14 @@ def compute_instr(self, instr, imm, rd): instr_map[instr][opcode] ]) - @staticmethod + @staticmethod#TODO:fix def immediate(imm): - return format(int(imm) >> 12, '013b') + # Check if the input is in hexadecimal format. The immediate value of U-type instructions is 20 bits. + if isinstance(imm, str) and imm.startswith('0x'): + imm = int(imm, 16) + else: + imm = int(imm) + return format(int(imm), '020b') class _UJ(Instruction): def __repr__(self): @@ -204,6 +242,37 @@ def __str__(self): return "R Parser" def organize(self, tokens): + instr, rs1, imm, rd = tokens[0], None, None, None + if instr in ["amoadd.d",'amoadd.w',"amoand.d","amoand.w","amomax.w","amomax.d","amomaxu.d","amomaxu.w","amomin.d","amomin.w" ,\ + "amominu.d" ,"amominu.w","amoor.d","amoor.w","amoswap.d","amoswap.w","amoxor.d","amoxor.w",]: + instr=tokens[0] + rd=reg_map[tokens[1]] + rs2=reg_map[tokens[2]] + start=tokens[3].find('(') + end=tokens[3].find(')') + rs1=reg_map[tokens[3][start+1:end]] + return R(instr, rs1, rs2, rd) + if instr in ["fmv.x.d","fmv.w.x","fmv.x.w","fmv.d.x"]: + instr,rd ,rs1,= tokens[0], reg_map[tokens[1]],reg_map[tokens[2]] + return R(instr, rs1, "x0", rd) + elif instr in ["fsqrt.s","fclass.s","fcvt.s.wu","fcvt.s.w","fcvt.s.l","fcvt.s.lu","fcvt.w.s","fcvt.wu.s","fcvt.l.s","fcvt.lu.s", + "fsqrt.d","fclass.d","fcvt.d.wu","fcvt.d.w","fcvt.d.l","fcvt.d.lu","fcvt.w.d","fcvt.wu.d","fcvt.l.d","fcvt.lu.d", + "fcvt.s.d","fcvt.d.s", + ]:#R type instructions with two registers + instr, rs1, rd = tokens[0], reg_map[tokens[2]], reg_map[tokens[1]] + rs2='00000' + if instr in ["fcvt.s.wu","fcvt.d.wu","fcvt.wu.s","fcvt.s.d","fcvt.wu.d"]: + rs2='x1'#00001 + elif instr in ["fcvt.s.l","fcvt.d.l","fcvt.l.s","fcvt.l.d"]: + rs2='x2'#00010 + elif instr in ["fcvt.s.lu","fcvt.d.lu","fcvt.lu.s","fcvt.lu.d"]: + rs2="x3"#00011 + return R(instr, rs1, rs2, rd) + elif instr in ["fmadd.s","fnmadd.s","fmsub.s","fnmsub.s", + "fmadd.d","fnmadd.d","fmsub.d","fnmsub.d"]:#R type instructions with four registers + instr, rs3,rs2,rs1, rd = tokens[0],reg_map[tokens[4]], reg_map[tokens[3]], reg_map[tokens[2]], reg_map[tokens[1]] + return R4(instr, rs3,rs2,rs1, rd) + instr, rs1, rs2, rd = tokens[0], reg_map[tokens[2]], reg_map[tokens[3]], reg_map[tokens[1]] return R(instr, rs1, rs2, rd) @@ -225,22 +294,39 @@ def organize(self, tokens): rs1, imm, rd = reg_map[tokens[1]], 0, reg_map["x1"] elif instr == "lw": rs1, imm, rd = reg_map[tokens[3]], tokens[2], reg_map[tokens[1]] - elif instr == 'ld': + elif instr in ['ld','lb','lh']: rs1, imm, rd = reg_map[tokens[3]], tokens[2], reg_map[tokens[1]] + elif instr in ['lbu','lhu','lwu',"flw","fld"]: + start=tokens[2].find('(') + end=tokens[2].find(')') + rs1=reg_map[tokens[2][start+1:end]] + imm=tokens[2][0:start] + rd=reg_map[tokens[1]] + elif instr in["CSRRW"]: + rs1, csr, rd = reg_map[tokens[3]], tokens[2], reg_map[tokens[1]] + csr_to_number={'fflags':'110000000000'} + csr=csr_to_number[csr] + return I(instr, rs1, csr, rd) else: rs1, imm, rd = reg_map[tokens[2]], tokens[3], reg_map[tokens[1]] - return I(instr, rs1, imm, rd) class _S_parse(InstructionParser): def __repr__(self): return "S Parser" - def __str__(self): return "S Parser" def organize(self, tokens): + instr=tokens[0] + if instr in ["fsw","fsd"]: + rs2=reg_map[tokens[1]] + start=tokens[2].find('(') + end=tokens[2].find(')') + rs1=reg_map[tokens[2][start+1:end]] + imm= tokens[2][0:start] + return S(instr, rs1, rs2, imm) instr, rs1, rs2, imm = tokens[0], reg_map[tokens[3]], reg_map[tokens[1]], tokens[2] return S(instr, rs1, rs2, imm) @@ -266,7 +352,7 @@ def __str__(self): return "U Parser" def organize(self, tokens): - instr, imm, rd = tokens[0], tokens[1], reg_map[tokens[2]] + instr,rd , imm = tokens[0], reg_map[tokens[1]],tokens[2], #Change the parameter input order. The normal order is instr rd imm order. return U(instr, imm, rd) class _UJ_parse(InstructionParser): @@ -350,7 +436,7 @@ def instruction_map(): return imap -R, I, S, SB, U, UJ = _R(), _I(), _S(), _SB(), _U(), _UJ() +R, I, S, SB, U, UJ, R4 = _R(), _I(), _S(), _SB(), _U(), _UJ(),_R4() Rp, Ip, Sp, SBp, Up, UJp, Psp = _R_parse(), _I_parse(), _S_parse(), _SB_parse(), _U_parse(), _UJ_parse(), _Pseudo_parse() reg_map, instr_map = register_map(), instruction_map() @@ -360,26 +446,34 @@ def instruction_map(): "sltu", "xor", "srl", "sra", "or", "and", "addw", "subw", "sllw", - "slrw", "sraw", "mul", - "mulh", "mulu", "mulsu", - "div", "divu", "rem", - "remu" + "slrw", "sraw", "mul","mulw", + "mulh", "mulhu", "mulhsu", + "div","divw", "divu","divuw", "rem", + "remu","remw","remuw", + "amoadd.d","amoadd.w","amoand.d","amoand.w","amomax.w","amomax.d","amomaxu.d","amomaxu.w","amomin.d","amomin.w", + "amominu.d" ,"amominu.w","amoor.d","amoor.w","amoswap.d","amoswap.w","amoxor.d","amoxor.w", + "fadd.s","fmv.x.w","fsub.s","fmul.s","fdiv.s","feq.s","fsqrt.s","fmin.s","fmax.s","fle.s","flt.s","fmadd.s","fnmadd.s","fmsub.s","fnmsub.s","fmv.w.x", + "fadd.d","fmv.x.d","fsub.d","fmul.d","fdiv.d","feq.d","fsqrt.d","fmin.d","fmax.d","fle.d","flt.d","fmadd.d","fnmadd.d","fmsub.d","fnmsub.d","fmv.d.x", + "fcvt.s.d","fcvt.d.s", + "fclass.s","fcvt.s.wu","fcvt.s.w","fcvt.s.l","fcvt.s.lu","fcvt.w.s","fcvt.wu.s","fcvt.l.s","fcvt.lu.s","fsgnj.s","fsgnjn.s","fsgnjx.s", + "fclass.d","fcvt.d.wu","fcvt.d.w","fcvt.d.l","fcvt.d.lu","fcvt.w.d","fcvt.wu.d","fcvt.l.d","fcvt.lu.d","fsgnj.d","fsgnjn.d","fsgnjx.d", ] I_instr = [ "addi", "lb", "lw", - "ld", "lbu", "lhu", + "ld", "lbu", "lhu","lh", "lwu", "fence", "fence.i", "slli", "slti", "sltiu", - "xori", "slri", "srai", + "xori", "srli", "srai", "ori", "andi", "addiw", "slliw", "srliw", "sraiw", "jalr", "ecall", "ebreak", "CSRRW", "CSRRS","CSRRC", - "CSRRWI", "CSRRSI", "CSRRCI" + "CSRRWI", "CSRRSI", "CSRRCI" , + "flw","fld" ] S_instr = [ "sw", "sb", "sh", - "sd" + "sd","fsw","fsd", ] SB_instr = [ "beq", "bne", "blt", diff --git a/tests/assembly/test9.s b/tests/assembly/test9.s new file mode 100644 index 0000000..45a68a9 --- /dev/null +++ b/tests/assembly/test9.s @@ -0,0 +1,6 @@ +fcvt.s.wu f1 x1 0xd010f0d3 +fcvt.d.wu f1 x1 0xd210f0d3 +fcvt.s.d f1 f2 0x401170d3 +fmadd.s f1, f2, f3, f4 0x203170c3 +fmadd.d f1, f2, f3, f4 0x223170c3 +amoadd.d x1, x2, (x3) 0x0021b0af \ No newline at end of file