# RV32I Base Instruction Set # add d,s,t 00000033 fe00707f SIMPLE (0, 0) :add rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x0 & funct7=0x0 { rd = rs1 + rs2; } # addi d,s,j 00000013 0000707f SIMPLE (0, 0) :addi rd,rs1,immI is rs1 & immI & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x0 { rd = rs1 + immI; } # nop 00000013 ffffffff ALIAS (0, 0) :nop is op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x0 & op0711=0x0 & op1531=0x0 { local NOP:1 = 0; NOP = NOP; } # mv d,s 00000013 fff0707f ALIAS (0, 0) :mv rd,rs1 is rs1 & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x0 & op2031=0x0 { rd = rs1; } # li d,j 00000013 000ff07f ALIAS (0, 0) :li rd,immI is immI & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x0 & op1519=0x0 { #TODO alias of addi rd,zero,0x0 is an issue rd = immI; } # Resolve conflict between: mv rd,zero and li rd,0x0 # ATTN this implementation uses mv rd,zero :mv rd,rs1 is rs1 & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x0 & op1531=0x0 { rd = rs1; } # and d,s,t 00007033 fe00707f SIMPLE (0, 0) :and rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x7 & funct7=0x0 { rd = rs1 & rs2; } # andi d,s,j 00007013 0000707f SIMPLE (0, 0) :andi rd,rs1,immI is rs1 & immI & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x7 { rd = rs1 & immI; } # auipc d,u 00000017 0000007f SIMPLE (0, 0) :auipc rd,immU is immU & rd & op0001=0x3 & op0204=0x5 & op0506=0x0 { rd = immU + inst_start; } # beq s,t,p 00000063 0000707f CONDBRANCH (0, 0) :beq rs1,rs2,immSB is immSB & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x3 & funct3=0x0 { if (rs1 == rs2) goto immSB; } # bge s,t,p 00005063 0000707f CONDBRANCH (0, 0) :bge rs1,rs2,immSB is immSB & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x3 & funct3=0x5 { if (rs1 s>= rs2) goto immSB; } # bgeu s,t,p 00007063 0000707f CONDBRANCH (0, 0) :bgeu rs1,rs2,immSB is immSB & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x3 & funct3=0x7 { if (rs1 >= rs2) goto immSB; } # blt s,t,p 00004063 0000707f CONDBRANCH (0, 0) :blt rs1,rs2,immSB is immSB & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x3 & funct3=0x4 { if (rs1 s< rs2) goto immSB; } # bltu s,t,p 00006063 0000707f CONDBRANCH (0, 0) :bltu rs1,rs2,immSB is immSB & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x3 & funct3=0x6 { if (rs1 < rs2) goto immSB; } # bne s,t,p 00001063 0000707f CONDBRANCH (0, 0) :bne rs1,rs2,immSB is immSB & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x3 & funct3=0x1 { if (rs1 != rs2) goto immSB; } # ebreak 00100073 ffffffff SIMPLE (0, 0) :ebreak is op0001=0x3 & op0204=0x4 & op0506=0x3 & funct3=0x0 & op0711=0x0 & op1531=0x20 { ebreak(); } # ecall 00000073 ffffffff SIMPLE (0, 0) :ecall is op0001=0x3 & op0204=0x4 & op0506=0x3 & funct3=0x0 & op0711=0x0 & op1531=0x0 { ecall(); } # fence P,Q 0000000f f00fffff SIMPLE (0, 0) :fence pred,succ is pred & succ & op0001=0x3 & op0204=0x3 & op0506=0x0 & funct3=0x0 & fm=0x0 & op0711=0x0 & op1519=0x0 { fence(); } # jal d,a 0000006f 0000007f JSR (0, 0) # call for rd = RA|T0 set to inst_next :jal rd,immUJ is immUJ & rd & (r0711=1 | r0711=5) & op0001=0x3 & op0204=0x3 & op0506=0x3 { rd = inst_next; call immUJ; } # goto for all other rd set to inst_next :jal rd,immUJ is immUJ & rd & r0711 & op0001=0x3 & op0204=0x3 & op0506=0x3 { rd = inst_next; goto immUJ; } # j a 0000006f 00000fff BRANCH|ALIAS (0, 0) :j immUJ is immUJ & op0001=0x3 & op0204=0x3 & op0506=0x3 & op0711=0x0 { goto immUJ; } # jalr d,s,j 00000067 0000707f JSR (0, 0) # call for rd = RA|T0 set to inst_next :jalr rd,rs1,immI is rs1 & immI & rd & (r0711=1 | r0711=5) & op0001=0x3 & op0204=0x1 & op0506=0x3 & funct3=0x0 { local ea:$(XLEN) = (rs1 + immI) & ~1; rd = inst_next; call [ea]; } # goto for all other rd set to inst_next :jalr rd,rs1,immI is rs1 & immI & rd & r0711 & op0001=0x3 & op0204=0x1 & op0506=0x3 & funct3=0x0 { local ea:$(XLEN) = (rs1 + immI) & ~1; rd = inst_next; goto [ea]; } # jr o(s) 00000067 00007fff BRANCH|ALIAS (0, 0) :jr immI(rs1) is immI & rs1 & op0001=0x3 & op0204=0x1 & op0506=0x3 & funct3=0x0 & op0711=0x0 { local ea:$(XLEN) = (rs1 + immI) & ~1; goto [ea]; } # jr s 00000067 fff07fff BRANCH|ALIAS (0, 0) :jr rs1 is rs1 & op0001=0x3 & op0204=0x1 & op0506=0x3 & funct3=0x0 & op0711=0x0 & op2031=0x0 { local ea:$(XLEN) = rs1 & ~1; goto [ea]; } # ret 00008067 ffffffff BRANCH|ALIAS (0, 0) :ret is op0001=0x3 & op0204=0x1 & op0506=0x3 & funct3=0x0 & op0711=0x0 & op2031=0x0 & op1519=1 { local ea:$(XLEN) = ra & ~1; return [ea]; } # lb d,o(s) 00000003 0000707f BYTE|DREF (0, 1) :lb rd,immI(rs1) is immI & rs1 & rd & op0001=0x3 & op0204=0x0 & op0506=0x0 & funct3=0x0 { local ea:$(XLEN) = rs1 + immI; rd = sext(*[ram]:1 ea); } # lbu d,o(s) 00004003 0000707f BYTE|DREF (0, 1) :lbu rd,immI(rs1) is immI & rs1 & rd & op0001=0x3 & op0204=0x0 & op0506=0x0 & funct3=0x4 { local ea:$(XLEN) = rs1 + immI; rd = zext(*[ram]:1 ea); } # lh d,o(s) 00001003 0000707f WORD|DREF (0, 2) :lh rd,immI(rs1) is immI & rs1 & rd & op0001=0x3 & op0204=0x0 & op0506=0x0 & funct3=0x1 { local ea:$(XLEN) = rs1 + immI; rd = sext(*[ram]:2 ea); } # lhu d,o(s) 00005003 0000707f WORD|DREF (0, 2) :lhu rd,immI(rs1) is immI & rs1 & rd & op0001=0x3 & op0204=0x0 & op0506=0x0 & funct3=0x5 { local ea:$(XLEN) = rs1 + immI; rd = zext(*[ram]:2 ea); } # lui d,u 00000037 0000007f SIMPLE (0, 0) :lui rd,immU is immU & rd & op0001=0x3 & op0204=0x5 & op0506=0x1 { rd = immU; } # lw d,o(s) 00002003 0000707f DWORD|DREF (0, 4) :lw rd,immI(rs1) is immI & rs1 & rd & op0001=0x3 & op0204=0x0 & op0506=0x0 & funct3=0x2 { local ea:$(XLEN) = rs1 + immI; assignW(rd, *[ram]:4 ea); } # or d,s,t 00006033 fe00707f SIMPLE (0, 0) :or rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x6 & funct7=0x0 { rd = rs1 | rs2; } # ori d,s,j 00006013 0000707f SIMPLE (0, 0) :ori rd,rs1,immI is rs1 & immI & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x6 { rd = rs1 | immI; } # sb t,q(s) 00000023 0000707f BYTE|DREF (0, 1) :sb rs2,immS(rs1) is immS & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x1 & funct3=0x0 { local ea:$(XLEN) = rs1 + immS; *[ram]:1 ea = rs2:1; } # sh t,q(s) 00001023 0000707f WORD|DREF (0, 2) :sh rs2,immS(rs1) is immS & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x1 & funct3=0x1 { local ea:$(XLEN) = rs1 + immS; *[ram]:2 ea = rs2:2; } # sll d,s,t 00001033 fe00707f SIMPLE (0, 0) :sll rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x1 & funct7=0x0 { local shift:$(XLEN) = rs2 & ($(ADDRSIZE) - 1); rd = rs1 << shift; } # slli d,s,> 00001013 fc00707f SIMPLE (0, 0) :slli rd,rs1,shamt6 is rs1 & shamt6 & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x1 & op2631=0x0 { rd = rs1 << shamt6; } # slt d,s,t 00002033 fe00707f SIMPLE (0, 0) :slt rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x2 & funct7=0x0 { rd = zext(rs1 s< rs2); } # slti d,s,j 00002013 0000707f SIMPLE (0, 0) :slti rd,rs1,immI is rs1 & immI & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x2 { rd = zext(rs1 s< immI); } # sltiu d,s,j 00003013 0000707f SIMPLE (0, 0) :sltiu rd,rs1,immI is rs1 & immI & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x3 { rd = zext(rs1 < immI); } # sltu d,s,t 00003033 fe00707f SIMPLE (0, 0) :sltu rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x3 & funct7=0x0 { rd = zext(rs1 < rs2); } # sra d,s,t 40005033 fe00707f SIMPLE (0, 0) :sra rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x5 & funct7=0x20 { local shift:$(XLEN) = rs2 & ($(ADDRSIZE) - 1); rd = rs1 s>> shift; } # srai d,s,> 40005013 fc00707f SIMPLE (0, 0) :srai rd,rs1,shamt6 is rs1 & shamt6 & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x5 & op2631=0x10 { rd = rs1 s>> shamt6; } # srl d,s,t 00005033 fe00707f SIMPLE (0, 0) :srl rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x5 & funct7=0x0 { local shift:$(XLEN) = rs2 & ($(ADDRSIZE) - 1); rd = rs1 >> shift; } # srli d,s,> 00005013 fc00707f SIMPLE (0, 0) :srli rd,rs1,shamt6 is rs1 & shamt6 & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x5 & op2631=0x0 { rd = rs1 >> shamt6; } # sub d,s,t 40000033 fe00707f SIMPLE (0, 0) :sub rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x0 & funct7=0x20 { rd = rs1 - rs2; } # neg d,t 40000033 fe0ff07f ALIAS (0, 0) :neg rd,rs2 is rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x0 & funct7=0x20 & op1519=0x0 { rd = -rs2; } # sw t,q(s) 00002023 0000707f DWORD|DREF (0, 4) :sw rs2,immS(rs1) is immS & rs2 & rs1 & op0001=0x3 & op0204=0x0 & op0506=0x1 & funct3=0x2 { local ea:$(XLEN) = rs1 + immS; *[ram]:4 ea = rs2:4; } # unimp c0001073 ffffffff SIMPLE (0, 0) :unimp is op0001=0x3 & op0204=0x4 & op0506=0x3 & funct3=0x1 & op0711=0x0 & op1531=0x18000 { local excaddr:$(XLEN) = inst_start; local target:$(XLEN) = unimp(excaddr); goto [target]; } # xor d,s,t 00004033 fe00707f SIMPLE (0, 0) :xor rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x4 & op0506=0x1 & funct3=0x4 & funct7=0x0 { rd = rs1 ^ rs2; } # xori d,s,j 00004013 0000707f SIMPLE (0, 0) :xori rd,rs1,immI is rs1 & immI & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x4 { rd = rs1 ^ immI; } # not d,s fff04013 fff0707f ALIAS (0, 0) :not rd,rs1 is rs1 & rd & op0001=0x3 & op0204=0x4 & op0506=0x0 & funct3=0x4 & op2031=0xfff { rd = ~rs1; }