
.definition

clz       =  [011000000000.....001.....0010011]
ctz       =  [011000000001.....001.....0010011]
cpop      =  [011000000010.....001.....0010011]
sext_b    =  [011000000100.....001.....0010011]
sext_h    =  [011000000101.....001.....0010011]

min       =  [0000101..........100.....0110011]
max       =  [0000101..........110.....0110011]
minu      =  [0000101..........101.....0110011]
maxu      =  [0000101..........111.....0110011]

andn      =  [0100000..........111.....0110011]
orn       =  [0100000..........110.....0110011]
xnor      =  [0100000..........100.....0110011]

#pack     =  [0000100..........100.....0110011]
zext_h    =  [000010000000.....100.....0110011]
pack1     =  [000010000001.....100.....0110011]
pack2     =  [000010000010.....100.....0110011]
pack3     =  [000010000011.....100.....0110011]
pack4     =  [000010000100.....100.....0110011]
pack5     =  [000010000101.....100.....0110011]
pack6     =  [000010000110.....100.....0110011]
pack7     =  [000010000111.....100.....0110011]
pack8     =  [000010001000.....100.....0110011]
pack9     =  [000010001001.....100.....0110011]
pack10    =  [000010001010.....100.....0110011]
pack11    =  [000010001011.....100.....0110011]
pack12    =  [000010001100.....100.....0110011]
pack13    =  [000010001101.....100.....0110011]
pack14    =  [000010001110.....100.....0110011]
pack15    =  [000010001111.....100.....0110011]
pack16    =  [000010010000.....100.....0110011]
pack17    =  [000010010001.....100.....0110011]
pack18    =  [000010010010.....100.....0110011]
pack19    =  [000010010011.....100.....0110011]
pack20    =  [000010010100.....100.....0110011]
pack21    =  [000010010101.....100.....0110011]
pack22    =  [000010010110.....100.....0110011]
pack23    =  [000010010111.....100.....0110011]
pack24    =  [000010011000.....100.....0110011]
pack25    =  [000010011001.....100.....0110011]
pack26    =  [000010011010.....100.....0110011]
pack27    =  [000010011011.....100.....0110011]
pack28    =  [000010011100.....100.....0110011]
pack29    =  [000010011101.....100.....0110011]
pack30    =  [000010011110.....100.....0110011]
pack31    =  [000010011111.....100.....0110011]

packu     =  [0100100..........100.....0110011]
packh     =  [0000100..........111.....0110011]
rol       =  [0110000..........001.....0110011]
ror       =  [0110000..........101.....0110011]
rori      =  [0110000..........101.....0010011]

sh1add    =  [0010000..........010.....0110011]
sh2add    =  [0010000..........100.....0110011]
sh3add    =  [0010000..........110.....0110011]

bset      =  [0010100..........001.....0110011]
bclr      =  [0100100..........001.....0110011]
binv      =  [0110100..........001.....0110011]
bext      =  [0100100..........101.....0110011]

bseti     =  [0010100..........001.....0010011]
bclri     =  [0100100..........001.....0010011]
binvi     =  [0110100..........001.....0010011]
bexti     =  [0100100..........101.....0010011]

grev      =  [0110100..........101.....0110011]
#grevi    =  [01101............101.....0010011]
grevi0    =  [011010000000.....101.....0010011]
grevi1    =  [011010000001.....101.....0010011]
grevi2    =  [011010000010.....101.....0010011]
grevi3    =  [011010000011.....101.....0010011]
grevi4    =  [011010000100.....101.....0010011]
grevi5    =  [011010000101.....101.....0010011]
grevi6    =  [011010000110.....101.....0010011]
grevi7    =  [011010000111.....101.....0010011]
grevi8    =  [011010001000.....101.....0010011]
grevi9    =  [011010001001.....101.....0010011]
grevi10   =  [011010001010.....101.....0010011]
grevi11   =  [011010001011.....101.....0010011]
grevi12   =  [011010001100.....101.....0010011]
grevi13   =  [011010001101.....101.....0010011]
grevi14   =  [011010001110.....101.....0010011]
grevi15   =  [011010001111.....101.....0010011]
grevi16   =  [011010010000.....101.....0010011]
grevi17   =  [011010010001.....101.....0010011]
grevi18   =  [011010010010.....101.....0010011]
grevi19   =  [011010010011.....101.....0010011]
grevi20   =  [011010010100.....101.....0010011]
grevi21   =  [011010010101.....101.....0010011]
grevi22   =  [011010010110.....101.....0010011]
grevi23   =  [011010010111.....101.....0010011]
#grevi24  =  [011010011000.....101.....0010011]    # REV8
rev8      =  [011010011000.....101.....0010011]
grevi25   =  [011010011001.....101.....0010011]
grevi26   =  [011010011010.....101.....0010011]
grevi27   =  [011010011011.....101.....0010011]
grevi28   =  [011010011100.....101.....0010011]
grevi29   =  [011010011101.....101.....0010011]
grevi30   =  [011010011110.....101.....0010011]
grevi31   =  [011010011111.....101.....0010011]

gorc      =  [0010100..........101.....0110011]
#gorci    =  [00101............101.....0010011]
gorci0    =  [001010000000.....101.....0010011]
gorci1    =  [001010000001.....101.....0010011]
gorci2    =  [001010000010.....101.....0010011]
gorci3    =  [001010000011.....101.....0010011]
gorci4    =  [001010000100.....101.....0010011]
gorci5    =  [001010000101.....101.....0010011]
gorci6    =  [001010000110.....101.....0010011]
#gorci7   =  [001010000111.....101.....0010011]    # ORC_B
orc_b     =  [001010000111.....101.....0010011]
gorci8    =  [001010001000.....101.....0010011]
gorci9    =  [001010001001.....101.....0010011]
gorci10   =  [001010001010.....101.....0010011]
gorci11   =  [001010001011.....101.....0010011]
gorci12   =  [001010001100.....101.....0010011]
gorci13   =  [001010001101.....101.....0010011]
gorci14   =  [001010001110.....101.....0010011]
gorci15   =  [001010001111.....101.....0010011]
gorci16   =  [001010010000.....101.....0010011]
gorci17   =  [001010010001.....101.....0010011]
gorci18   =  [001010010010.....101.....0010011]
gorci19   =  [001010010011.....101.....0010011]
gorci20   =  [001010010100.....101.....0010011]
gorci21   =  [001010010101.....101.....0010011]
gorci22   =  [001010010110.....101.....0010011]
gorci23   =  [001010010111.....101.....0010011]
gorci24   =  [001010011000.....101.....0010011]
gorci25   =  [001010011001.....101.....0010011]
gorci26   =  [001010011010.....101.....0010011]
gorci27   =  [001010011011.....101.....0010011]
gorci28   =  [001010011100.....101.....0010011]
gorci29   =  [001010011101.....101.....0010011]
gorci30   =  [001010011110.....101.....0010011]
gorci31   =  [001010011111.....101.....0010011]


shfl      =  [0000100..........001.....0110011]
shfli     =  [00001000.........001.....0010011]

unshfl    =  [0000100..........101.....0110011]
unshfli   =  [00001000.........101.....0010011]

bdecompress =  [0100100..........110.....0110011]
bcompress   =  [0000100..........110.....0110011]

clmul     =  [0000101..........001.....0110011]
clmulr    =  [0000101..........010.....0110011]
clmulh    =  [0000101..........011.....0110011]

crc32_b   =  [011000010000.....001.....0010011]
crc32_h   =  [011000010001.....001.....0010011]
crc32_w   =  [011000010010.....001.....0010011]
crc32c_b  =  [011000011000.....001.....0010011]
crc32c_h  =  [011000011001.....001.....0010011]
crc32c_w  =  [011000011010.....001.....0010011]

bfp       =  [0100100..........111.....0110011]

xperm_n   =  [0010100..........010.....0110011]
xperm_b   =  [0010100..........100.....0110011]
xperm_h   =  [0010100..........110.....0110011]






add       =  [0000000..........000.....0110011]
addi      =  [.................000.....0010011]

sub       =  [0100000..........000.....0110011]

and       =  [0000000..........111.....0110011]
andi      =  [.................111.....0010011]

or        =  [0000000..........110.....0110011]
ori       =  [.................110.....0010011]

xor       =  [0000000..........100.....0110011]
xori      =  [.................100.....0010011]

sll       =  [0000000..........001.....0110011]
slli      =  [0000000..........001.....0010011]

sra       =  [0100000..........101.....0110011]
srai      =  [0100000..........101.....0010011]

srl       =  [0000000..........101.....0110011]
srli      =  [0000000..........101.....0010011]

lui       =  [.........................0110111]
auipc     =  [.........................0010111]

slt       =  [0000000..........010.....0110011]
sltu      =  [0000000..........011.....0110011]
slti      =  [.................010.....0010011]
sltiu     =  [.................011.....0010011]

beq       =  [.................000.....1100011]
bne       =  [.................001.....1100011]
bge       =  [.................101.....1100011]
blt       =  [.................100.....1100011]
bgeu      =  [.................111.....1100011]
bltu      =  [.................110.....1100011]

jal       =  [.........................1101111]
jalr      =  [.................000.....1100111]

lb        =  [.................000.....0000011]
lh        =  [.................001.....0000011]
lw        =  [.................010.....0000011]

sb        =  [.................000.....0100011]
sh        =  [.................001.....0100011]
sw        =  [.................010.....0100011]

lbu       =  [.................100.....0000011]
lhu       =  [.................101.....0000011]

fence     =  [.000.............000.....0001111]
fence.i   =  [.................001.....0001111]

ebreak    =  [00000000000100000000000001110011]
ecall     =  [00000000000000000000000001110011]

mret      =  [00110000001000000000000001110011]

wfi       =  [00010000010100000000000001110011]

csrrc_ro  =  [............00000011.....1110011]
csrrc_rw0 =  [............1....011.....1110011]
csrrc_rw1 =  [.............1...011.....1110011]
csrrc_rw2 =  [..............1..011.....1110011]
csrrc_rw3 =  [...............1.011.....1110011]
csrrc_rw4 =  [................1011.....1110011]

csrrci_ro  = [............00000111.....1110011]
csrrci_rw0 = [............1....111.....1110011]
csrrci_rw1 = [.............1...111.....1110011]
csrrci_rw2 = [..............1..111.....1110011]
csrrci_rw3 = [...............1.111.....1110011]
csrrci_rw4 = [................1111.....1110011]

csrrs_ro  =  [............00000010.....1110011]
csrrs_rw0 =  [............1....010.....1110011]
csrrs_rw1 =  [.............1...010.....1110011]
csrrs_rw2 =  [..............1..010.....1110011]
csrrs_rw3 =  [...............1.010.....1110011]
csrrs_rw4 =  [................1010.....1110011]

csrrsi_ro  = [............00000110.....1110011]
csrrsi_rw0 = [............1....110.....1110011]
csrrsi_rw1 = [.............1...110.....1110011]
csrrsi_rw2 = [..............1..110.....1110011]
csrrsi_rw3 = [...............1.110.....1110011]
csrrsi_rw4 = [................1110.....1110011]


csrw  =       [.................001000001110011]
csrrw0 =      [.................001....11110011]
csrrw1 =      [.................001...1.1110011]
csrrw2 =      [.................001..1..1110011]
csrrw3 =      [.................001.1...1110011]
csrrw4 =      [.................0011....1110011]

csrwi   =     [.................101000001110011]
csrrwi0 =     [.................101....11110011]
csrrwi1 =     [.................101...1.1110011]
csrrwi2 =     [.................101..1..1110011]
csrrwi3 =     [.................101.1...1110011]
csrrwi4 =     [.................1011....1110011]

mul =        [0000001..........000.....0110011]
mulh =       [0000001..........001.....0110011]
mulhsu =     [0000001..........010.....0110011]
mulhu =      [0000001..........011.....0110011]

div =        [0000001..........100.....0110011]
divu =       [0000001..........101.....0110011]
rem =        [0000001..........110.....0110011]
remu =       [0000001..........111.....0110011]


.input

rv32i = {
        i[31]
        i[30]
        i[29]
        i[28]
        i[27]
        i[26]
        i[25]
        i[24]
        i[23]
        i[22]
        i[21]
        i[20]
        i[19]
        i[18]
        i[17]
        i[16]
        i[15]
        i[14]
        i[13]
        i[12]
        i[11]
        i[10]
        i[9]
        i[8]
        i[7]
        i[6]
        i[5]
        i[4]
        i[3]
        i[2]
        i[1]
        i[0]
}


.output

rv32i = {
      alu
      rs1
      rs2
      imm12
      rd
      shimm5
      imm20
      pc
      load
      store
      lsu
      add
      sub
      land
      lor
      lxor
      sll
      sra
      srl
      slt
      unsign
      condbr
      beq
      bne
      bge
      blt
      jal
      by
      half
      word
      csr_read
      csr_clr
      csr_set
      csr_write
      csr_imm
      presync
      postsync
      ebreak
      ecall
      mret
      mul
      rs1_sign
      rs2_sign
      low
      div
      rem
      fence
      fence_i
      clz
      ctz
      cpop
      sext_b
      sext_h
      min
      max
      pack
      packu
      packh
      rol
      ror
      zbb
      bset
      bclr
      binv
      bext
      zbs
      bcompress
      bdecompress
      zbe
      clmul
      clmulh
      clmulr
      zbc
      grev
      gorc
      shfl
      unshfl
      xperm_n
      xperm_b
      xperm_h
      zbp
      crc32_b
      crc32_h
      crc32_w
      crc32c_b
      crc32c_h
      crc32c_w
      zbr
      bfp
      zbf
      sh1add
      sh2add
      sh3add
      zba
      pm_alu
}

.decode

rv32i[clz]       =  { alu zbb     rs1     rd                       clz   }
rv32i[ctz]       =  { alu zbb     rs1     rd                       ctz   }
rv32i[cpop]      =  { alu zbb     rs1     rd                       cpop  }
rv32i[sext_b]    =  { alu zbb     rs1     rd                       sext_b}
rv32i[sext_h]    =  { alu zbb     rs1     rd                       sext_h}
rv32i[min]       =  { alu zbb     rs1 rs2 rd                sub    min   }
rv32i[max]       =  { alu zbb     rs1 rs2 rd                sub    max   }
rv32i[minu]      =  { alu zbb     rs1 rs2 rd  unsign        sub    min   }
rv32i[maxu]      =  { alu zbb     rs1 rs2 rd  unsign        sub    max   }
rv32i[andn]      =  { alu zbb zbp rs1 rs2 rd                       land  }
rv32i[orn]       =  { alu zbb zbp rs1 rs2 rd                       lor   }
rv32i[xnor]      =  { alu zbb zbp rs1 rs2 rd                       lxor  }
rv32i[packu]     =  { alu     zbp rs1 rs2 rd                       packu }
rv32i[packh]     =  { alu     zbp rs1 rs2 rd                       packh zbe zbf}
rv32i[rol]       =  { alu zbb zbp rs1 rs2 rd                       rol   }
rv32i[ror]       =  { alu zbb zbp rs1 rs2 rd                       ror   }
rv32i[rori]      =  { alu zbb zbp rs1     rd         shimm5        ror   }
rv32i[bset]      =  { alu zbs     rs1 rs2 rd                       bset  }
rv32i[bclr]      =  { alu zbs     rs1 rs2 rd                       bclr  }
rv32i[binv]      =  { alu zbs     rs1 rs2 rd                       binv  }
rv32i[bext]      =  { alu zbs     rs1 rs2 rd                       bext  }
rv32i[bseti]     =  { alu zbs     rs1     rd         shimm5        bset  }
rv32i[bclri]     =  { alu zbs     rs1     rd         shimm5        bclr  }
rv32i[binvi]     =  { alu zbs     rs1     rd         shimm5        binv  }
rv32i[bexti]     =  { alu zbs     rs1     rd         shimm5        bext  }
rv32i[sh1add]    =  { alu zba     rs1 rs2 rd                       sh1add}
rv32i[sh2add]    =  { alu zba     rs1 rs2 rd                       sh2add}
rv32i[sh3add]    =  { alu zba     rs1 rs2 rd                       sh3add}

#v32i[pack]      =  { alu     zbp rs1 rs2 rd                       pack  zbe zbf}
rv32i[zext_h]    =  { alu zbb zbp rs1 rs2 rd                       pack  zbe zbf}   # pack with rs2=x0
rv32i[pack{1-31}]=  { alu     zbp rs1 rs2 rd                       pack  zbe zbf}

rv32i[mul]       =  { mul         rs1 rs2 rd low                         }
rv32i[mulh]      =  { mul         rs1 rs2 rd rs1_sign rs2_sign           }
rv32i[mulhu]     =  { mul         rs1 rs2 rd                             }
rv32i[mulhsu]    =  { mul         rs1 rs2 rd rs1_sign                    }
rv32i[bcompress]   =  { mul zbe     rs1 rs2 rd                       bcompress   }
rv32i[bdecompress] =  { mul zbe     rs1 rs2 rd                       bdecompress }
rv32i[clmul]     =  { mul zbc     rs1 rs2 rd                       clmul }
rv32i[clmulh]    =  { mul zbc     rs1 rs2 rd                       clmulh}
rv32i[clmulr]    =  { mul zbc     rs1 rs2 rd                       clmulr}

rv32i[crc32_b]   =  { mul zbr     rs1     rd                       crc32_b}
rv32i[crc32_h]   =  { mul zbr     rs1     rd                       crc32_h}
rv32i[crc32_w]   =  { mul zbr     rs1     rd                       crc32_w}
rv32i[crc32c_b]  =  { mul zbr     rs1     rd                       crc32c_b}
rv32i[crc32c_h]  =  { mul zbr     rs1     rd                       crc32c_h}
rv32i[crc32c_w]  =  { mul zbr     rs1     rd                       crc32c_w}

rv32i[bfp]       =  { mul zbf     rs1 rs2 rd                       bfp   }

rv32i[grev]          =  { mul     zbp rs1 rs2 rd                       grev  }

rv32i[grevi{0-23}]   =  { mul     zbp rs1     rd         shimm5        grev  }
rv32i[grevi{25-31}]  =  { mul     zbp rs1     rd         shimm5        grev  }

rv32i[rev8]          =  { alu zbb zbp rs1     rd         shimm5        grev  } # grevi24

rv32i[gorc]          =  { mul     zbp rs1 rs2 rd                       gorc  }

rv32i[gorci{0-6}]    =  { mul     zbp rs1     rd         shimm5        gorc  }
rv32i[gorci{8-31}]   =  { mul     zbp rs1     rd         shimm5        gorc  }

rv32i[orc_b]         =  { alu zbb zbp rs1     rd         shimm5        gorc  }  # gorci7


rv32i[shfl]      =  { mul     zbp rs1 rs2 rd                       shfl  }
rv32i[shfli]     =  { mul     zbp rs1     rd         shimm5        shfl  }

rv32i[unshfl]    =  { mul     zbp rs1 rs2 rd                       unshfl}
rv32i[unshfli]   =  { mul     zbp rs1     rd         shimm5        unshfl}

rv32i[xperm_n]   =  { mul     zbp rs1 rs2 rd                       xperm_n}
rv32i[xperm_b]   =  { mul     zbp rs1 rs2 rd                       xperm_b}
rv32i[xperm_h]   =  { mul     zbp rs1 rs2 rd                       xperm_h}



rv32i[div]       =  { div rs1 rs2 rd           }
rv32i[divu]      =  { div rs1 rs2 rd unsign    }
rv32i[rem]       =  { div rs1 rs2 rd        rem}
rv32i[remu]      =  { div rs1 rs2 rd unsign rem}

rv32i[add]       =  { alu rs1 rs2   rd add pm_alu }
rv32i[addi]      =  { alu rs1 imm12 rd add pm_alu }

rv32i[sub]       =  { alu rs1 rs2   rd sub pm_alu }

rv32i[and]       =  { alu rs1 rs2   rd land pm_alu }
rv32i[andi]      =  { alu rs1 imm12 rd land pm_alu }

rv32i[or]        =  { alu rs1 rs2   rd lor pm_alu }
rv32i[ori]       =  { alu rs1 imm12 rd lor pm_alu }

rv32i[xor]       =  { alu rs1 rs2   rd lxor pm_alu }
rv32i[xori]      =  { alu rs1 imm12 rd lxor pm_alu }

rv32i[sll]       =  { alu rs1 rs2    rd sll pm_alu }
rv32i[slli]      =  { alu rs1 shimm5 rd sll pm_alu }

rv32i[sra]       =  { alu rs1 rs2    rd sra pm_alu }
rv32i[srai]      =  { alu rs1 shimm5 rd sra pm_alu }

rv32i[srl]       =  { alu rs1 rs2    rd srl pm_alu }
rv32i[srli]      =  { alu rs1 shimm5 rd srl pm_alu }

rv32i[lui]       =  { alu imm20    rd lor pm_alu }
rv32i[auipc]     =  { alu imm20 pc rd add pm_alu }


rv32i[slt]    =     { alu rs1 rs2    rd sub slt        pm_alu }
rv32i[sltu]    =    { alu rs1 rs2    rd sub slt unsign pm_alu }
rv32i[slti]    =    { alu rs1 imm12  rd sub slt        pm_alu }
rv32i[sltiu]    =   { alu rs1 imm12  rd sub slt unsign pm_alu }

rv32i[beq]    =     { alu rs1 rs2 sub condbr beq }
rv32i[bne]    =     { alu rs1 rs2 sub condbr bne }
rv32i[bge]    =     { alu rs1 rs2 sub condbr bge }
rv32i[blt]    =     { alu rs1 rs2 sub condbr blt }
rv32i[bgeu]    =    { alu rs1 rs2 sub condbr bge unsign }
rv32i[bltu]    =    { alu rs1 rs2 sub condbr blt unsign }

rv32i[jal]    =     { alu imm20 rd pc    jal }
rv32i[jalr]    =    { alu rs1   rd imm12 jal }



rv32i[lb] =      { lsu load rs1 rd by    }
rv32i[lh] =      { lsu load rs1 rd half  }
rv32i[lw] =      { lsu load rs1 rd word  }
rv32i[lbu] =     { lsu load rs1 rd by   unsign  }
rv32i[lhu] =     { lsu load rs1 rd half unsign  }

rv32i[sb] =      { lsu store rs1 rs2 by   }
rv32i[sh] =      { lsu store rs1 rs2 half }
rv32i[sw] =      { lsu store rs1 rs2 word }


rv32i[fence] =   { alu lor fence presync}

# fence.i has fence effect in addtion to flush I$ and redirect
rv32i[fence.i] = { alu lor fence fence_i presync postsync}

# nops for now

rv32i[ebreak] = {  alu rs1 imm12 rd lor ebreak postsync}
rv32i[ecall] =  {  alu rs1 imm12 rd lor ecall  postsync}
rv32i[mret] =   {  alu rs1 imm12 rd lor mret   postsync}

rv32i[wfi] =    {  alu rs1 imm12 rd lor pm_alu }

# csr means read

# csr_read - put csr on rs2 and rs1 0's
rv32i[csrrc_ro] =        { alu rd csr_read }

# put csr on rs2 and make rs1 0's into alu.  Save rs1 for csr_clr later
rv32i[csrrc_rw{0-4}] =   { alu rd csr_read rs1 csr_clr            presync postsync }

rv32i[csrrci_ro] =       { alu rd csr_read }

rv32i[csrrci_rw{0-4}] =  { alu rd csr_read rs1 csr_clr   csr_imm  presync postsync }

rv32i[csrrs_ro] =        { alu rd csr_read }

rv32i[csrrs_rw{0-4}] =   { alu rd csr_read rs1 csr_set            presync postsync }

rv32i[csrrsi_ro] =       { alu rd csr_read }

rv32i[csrrsi_rw{0-4}] =  { alu rd csr_read rs1 csr_set   csr_imm presync postsync }

rv32i[csrrw{0-4}] =     { alu rd csr_read rs1 csr_write         presync postsync }


rv32i[csrrwi{0-4}] =         { alu rd csr_read rs1 csr_write csr_imm presync postsync }

# optimize csr write only - pipelined
rv32i[csrw] =                { alu rd rs1 csr_write           }

rv32i[csrwi]       =         { alu rd     csr_write csr_imm   }


.end

