""" RISC-V Encoding recipes. The encoding recipes defined here more or less correspond to the RISC-V native instruction formats described in the reference: The RISC-V Instruction Set Manual Volume I: User-Level ISA Version 2.1 """ from __future__ import absolute_import from cretonne import EncRecipe from cretonne.formats import Binary, BinaryImm from cretonne.predicates import IsSignedInt # The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit # instructions have 11 as the two low bits, with bits 6:2 determining the base # opcode. # # Encbits for the 32-bit recipes are opcode[6:2] | (funct3 << 5) | ... # The functions below encode the encbits. def LOAD(funct3): assert funct3 <= 0b111 return 0b00000 | (funct3 << 5) def STORE(funct3): assert funct3 <= 0b111 return 0b01000 | (funct3 << 5) def BRANCH(funct3): assert funct3 <= 0b111 return 0b11000 | (funct3 << 5) def OPIMM(funct3, funct7=0): assert funct3 <= 0b111 return 0b00100 | (funct3 << 5) | (funct7 << 8) def OPIMM32(funct3, funct7=0): assert funct3 <= 0b111 return 0b00110 | (funct3 << 5) | (funct7 << 8) def OP(funct3, funct7): assert funct3 <= 0b111 assert funct7 <= 0b1111111 return 0b01100 | (funct3 << 5) | (funct7 << 8) def OP32(funct3, funct7): assert funct3 <= 0b111 assert funct7 <= 0b1111111 return 0b01110 | (funct3 << 5) | (funct7 << 8) # R-type 32-bit instructions: These are mostly binary arithmetic instructions. # The encbits are `opcode[6:2] | (funct3 << 5) | (funct7 << 8) R = EncRecipe('R', Binary) # R-type with an immediate shift amount instead of rs2. Rshamt = EncRecipe('Rshamt', BinaryImm) I = EncRecipe('I', BinaryImm, instp=IsSignedInt(BinaryImm.imm, 12))