diff --git a/bronzebeard/asm.py b/bronzebeard/asm.py index 6269e45..b3feb79 100644 --- a/bronzebeard/asm.py +++ b/bronzebeard/asm.py @@ -751,6 +751,8 @@ def cj_type(imm, *, opcode, funct3, cs=None): FENCE = partial(fence, opcode=0b0001111, funct3=0b000, rd=0, rs1=0, fm=0) # special syntax* ECALL = partial(i_type, opcode=0b1110011, funct3=0b000, rd=0, rs1=0, imm=0) # special syntax EBREAK = partial(i_type, opcode=0b1110011, funct3=0b000, rd=0, rs1=0, imm=1) # special syntax +MRET = partial(i_type, opcode=0b1110011, funct3=0b000, rd=0, rs1=0, imm=0b001100000010) # special syntax +WFI = partial(i_type, opcode=0b1110011, funct3=0b000, rd=0, rs1=0, imm=0b000100000101) # special syntax # RV32/RV64 "Zifencei" Instruction-Fetch Fence FENCE_I = partial(i_type, opcode=0b0001111, funct3=0b001, rd=0, rs1=0, imm=0) # special syntax @@ -864,6 +866,8 @@ def cj_type(imm, *, opcode, funct3, cs=None): IE_TYPE_INSTRUCTIONS = { 'ecall': ECALL, 'ebreak': EBREAK, + 'mret': MRET, + 'wfi': WFI, 'fence.i': FENCE_I, } @@ -2460,16 +2464,29 @@ def parse_item(line_tokens): return CATypeInstruction(line, name, rd_rs1, rs2) # cb-type instructions elif head in CB_TYPE_INSTRUCTIONS: - name, rs1, *imm = tokens + if len(tokens) != 3: + raise AssemblerError('cb-type instructions require exactly 3 args', line) + name, rs1, reference = tokens name = name.lower() + if is_int(reference): + imm = [reference] + else: + imm = ['%offset', reference] imm = parse_immediate(imm, line) return CBTypeInstruction(line, name, rs1, imm) # cj-type instructions elif head in CJ_TYPE_INSTRUCTIONS: - name, *imm = tokens + if len(tokens) != 2: + raise AssemblerError('cj-type instructions require exactly 2 args', line) + name, reference = tokens name = name.lower() + if is_int(reference): + imm = [reference] + else: + imm = ['%offset', reference] imm = parse_immediate(imm, line) return CJTypeInstruction(line, name, imm) + # pseudo instructions elif head in PSEUDO_INSTRUCTIONS: name, *args = tokens diff --git a/docs/instruction_reference.rst b/docs/instruction_reference.rst index 0019fa3..bf19ab5 100644 --- a/docs/instruction_reference.rst +++ b/docs/instruction_reference.rst @@ -124,6 +124,8 @@ Instruction Description :code:`fence succ, pred` order device I/O and memory accesses :code:`ecall` make a service request to the execution environment :code:`ebreak` return control to a debugging environment +:code:`mret` return execution from a trap +:code:`wfi` wait for interrupt =========================== =========== RV32M Standard Extension diff --git a/tests/test_isa_base_i.py b/tests/test_isa_base_i.py index e4ad1ae..24908bc 100644 --- a/tests/test_isa_base_i.py +++ b/tests/test_isa_base_i.py @@ -574,10 +574,14 @@ def test_fence(succ, pred, code): def test_ecall(): assert asm.ECALL() == 0b00000000000000000000000001110011 - def test_ebreak(): assert asm.EBREAK() == 0b00000000000100000000000001110011 +def test_wfi(): + assert asm.WFI() == 0b0001000_00101_0000000000000_1110011 + +def test_mret(): + assert asm.MRET() == 0b0011000_00010_0000000000000_1110011 @pytest.mark.parametrize( 'source, expected', [