@@ -163,6 +163,7 @@ def r_type(rd, rs1, rs2, *, opcode, funct3, funct7):
163163
164164 return code
165165
166+
166167# r-type variation for privileged instructions
167168def rp_type (rs1 , rs2 , * , rd , opcode , funct3 , funct7 ):
168169 rd = lookup_register (rd )
@@ -832,15 +833,15 @@ def cj_type(imm, *, opcode, funct3, cs=None):
832833C_SWSP = partial (css_type , opcode = 0b10 , funct3 = 0b110 )
833834
834835# RV32 Priv: Trap-Return Instructions
835- SRET = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , rs2 = 0b00010 , funct7 = 0b0001000 ) # special syntax
836- MRET = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , rs2 = 0b00010 , funct7 = 0b0011000 ) # special syntax
837- MNRET = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , rs2 = 0b00010 , funct7 = 0b0111000 ) # special syntax
836+ SRET = partial (i_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , imm = 0b000100000010 ) # special syntax
837+ MRET = partial (i_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , imm = 0b001100000010 ) # special syntax
838+ MNRET = partial (i_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , imm = 0b011100000010 ) # special syntax
838839
839840# RV32 Priv: Interrupt-Management Instructions
840- WFI = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , rs2 = 0b00101 , funct7 = 0b0001000 ) # special syntax
841+ WFI = partial (i_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , imm = 0b000100000101 ) # special syntax
841842
842843# RV32 Priv: Control Transfer Records Management Instructions
843- SCTRCLR = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , rs2 = 0b00100 , funct7 = 0b0001000 ) # special syntax
844+ SCTRCLR = partial (i_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , imm = 0b000100000100 ) # special syntax
844845
845846# RV32 Priv: Supervisor Memory-Management Instructions
846847SFENCE_VMA = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 ,funct7 = 0b0001001 ) # special syntax
@@ -863,8 +864,8 @@ def cj_type(imm, *, opcode, funct3, cs=None):
863864
864865# RV32 Priv: Svinval Memory-Management Extension
865866SINVAL_VMA = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , funct7 = 0b0001011 ) # special syntax
866- SFENCE_W_INVAL = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , rs2 = 0 , funct7 = 0b0001100 ) # special syntax
867- SFENCE_INVAL_IR = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , rs2 = 1 , funct7 = 0b0001100 ) # special syntax
867+ SFENCE_W_INVAL = partial (i_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , imm = 0b000110000000 ) # special syntax
868+ SFENCE_INVAL_IR = partial (i_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , rs1 = 0 , imm = 0b000110000001 ) # special syntax
868869HINVAL_VVMA = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , funct7 = 0b0010011 ) # special syntax
869870HINVAL_GVMA = partial (rp_type , opcode = 0b1110011 , rd = 0 , funct3 = 0b000 , funct7 = 0b0110011 ) # special syntax
870871
@@ -892,6 +893,19 @@ def cj_type(imm, *, opcode, funct3, cs=None):
892893 'remu' : REMU ,
893894}
894895
896+ RP_TYPE_INSTRUCTIONS = {
897+ # Privileged Instructions
898+ 'sfence.vma' : SFENCE_VMA ,
899+ 'hfence.vvma' : HFENCE_VVMA ,
900+ 'hfence.gvma' : HFENCE_GVMA ,
901+ 'hsv.b' : HSV_B ,
902+ 'hsv.h' : HSV_H ,
903+ 'hsv.w' : HSV_W ,
904+ 'sinval.vma' : SINVAL_VMA ,
905+ 'hinval.vvma' : HINVAL_VVMA ,
906+ 'hinval.gvma' : HINVAL_GVMA ,
907+ }
908+
895909I_TYPE_INSTRUCTIONS = {
896910 'jalr' : JALR ,
897911 'lb' : LB ,
@@ -913,10 +927,30 @@ def cj_type(imm, *, opcode, funct3, cs=None):
913927 'csrrci' : CSRRCI ,
914928}
915929
930+ IP_TYPE_INSTRUCTIONS = {
931+ # Privileged Instructions
932+ 'hlv.b' : HLV_B ,
933+ 'hlv.bu' : HLV_BU ,
934+ 'hlv.h' : HLV_H ,
935+ 'hlv.hu' : HLV_HU ,
936+ 'hlv.w' : HLV_W ,
937+ 'hlvx.hu' : HLVX_HU ,
938+ 'hlvx.wu' : HLVX_WU ,
939+ }
940+
916941IE_TYPE_INSTRUCTIONS = {
917942 'ecall' : ECALL ,
918943 'ebreak' : EBREAK ,
919944 'fence.i' : FENCE_I ,
945+
946+ # Privileged Instructions
947+ 'sret' : SRET ,
948+ 'mret' : MRET ,
949+ 'mnret' : MNRET ,
950+ 'wfi' : WFI ,
951+ 'sctrclr' : SCTRCLR ,
952+ 'sfence.w.inval' : SFENCE_W_INVAL ,
953+ 'sfence.inval.ir' : SFENCE_INVAL_IR ,
920954}
921955
922956S_TYPE_INSTRUCTIONS = {
@@ -1030,41 +1064,11 @@ def cj_type(imm, *, opcode, funct3, cs=None):
10301064 'c.j' : C_J ,
10311065}
10321066
1033- PRIV_INSTRUCTIONS = {
1034- 'sret' : SRET ,
1035- 'mret' : MRET ,
1036- 'mnret' : MNRET ,
1037-
1038- 'wfi' : WFI ,
1039-
1040- 'sctrclr' : SCTRCLR ,
1041-
1042- 'sfence.vma' : SFENCE_VMA ,
1043-
1044- 'hfence.vvma' : HFENCE_VVMA ,
1045- 'hfence.gvma' : HFENCE_GVMA ,
1046-
1047- 'hlv.b' : HLV_B ,
1048- 'hlv.bu' : HLV_BU ,
1049- 'hlv.h' : HLV_H ,
1050- 'hlv.hu' : HLV_HU ,
1051- 'hlv.w' : HLV_W ,
1052- 'hlvx.hu' : HLVX_HU ,
1053- 'hlvx.wu' : HLVX_WU ,
1054- 'hsv.b' : HSV_B ,
1055- 'hsv.h' : HSV_H ,
1056- 'hsv.w' : HSV_W ,
1057-
1058- 'sinval.vma' : SINVAL_VMA ,
1059- 'sfence.w.inval' : SFENCE_W_INVAL ,
1060- 'sfence.inval.ir' : SFENCE_INVAL_IR ,
1061- 'hinval.vvma' : HINVAL_VVMA ,
1062- 'hinval.gvma' : HINVAL_GVMA ,
1063- }
1064-
10651067INSTRUCTIONS = {}
10661068INSTRUCTIONS .update (R_TYPE_INSTRUCTIONS )
1069+ INSTRUCTIONS .update (RP_TYPE_INSTRUCTIONS )
10671070INSTRUCTIONS .update (I_TYPE_INSTRUCTIONS )
1071+ INSTRUCTIONS .update (IP_TYPE_INSTRUCTIONS )
10681072INSTRUCTIONS .update (IE_TYPE_INSTRUCTIONS )
10691073INSTRUCTIONS .update (S_TYPE_INSTRUCTIONS )
10701074INSTRUCTIONS .update (B_TYPE_INSTRUCTIONS )
@@ -1086,7 +1090,6 @@ def cj_type(imm, *, opcode, funct3, cs=None):
10861090INSTRUCTIONS .update (CA_TYPE_INSTRUCTIONS )
10871091INSTRUCTIONS .update (CB_TYPE_INSTRUCTIONS )
10881092INSTRUCTIONS .update (CJ_TYPE_INSTRUCTIONS )
1089- INSTRUCTIONS .update (PRIV_INSTRUCTIONS )
10901093
10911094PSEUDO_INSTRUCTIONS = {
10921095 'nop' ,
@@ -1638,6 +1641,29 @@ def args(self):
16381641 return [self .rd , self .rs1 , self .rs2 ]
16391642
16401643
1644+ # custom syntax for privileged instructions
1645+ class RPTypeInstruction (Instruction ):
1646+
1647+ def __init__ (self , line , name , rs1 , rs2 ):
1648+ super ().__init__ (line )
1649+ self .name = name
1650+ self .rs1 = rs1
1651+ self .rs2 = rs2
1652+
1653+ def __repr__ (self ):
1654+ s = '{}({!r}, rs1={!r}, rs2={!r})'
1655+ s = s .format (type (self ).__name__ , self .name , self .rs1 , self .rs2 )
1656+ return s
1657+
1658+ def __str__ (self ):
1659+ s = '{} {}, {}'
1660+ s = s .format (self .name , self .rs1 , self .rs2 )
1661+ return s
1662+
1663+ def args (self ):
1664+ return [self .rs1 , self .rs2 ]
1665+
1666+
16411667class ITypeInstruction (Instruction ):
16421668
16431669 def __init__ (self , line , name , rd , rs1 , imm , is_auipc_jump = False ):
@@ -1662,6 +1688,29 @@ def args(self):
16621688 return [self .rd , self .rs1 , self .imm ]
16631689
16641690
1691+ # custom syntax for privileged instructions
1692+ class IPTypeInstruction (Instruction ):
1693+
1694+ def __init__ (self , line , name , rd , rs1 ):
1695+ super ().__init__ (line )
1696+ self .name = name
1697+ self .rd = rd
1698+ self .rs1 = rs1
1699+
1700+ def __repr__ (self ):
1701+ s = '{}({!r}, rd={!r}, rs1={!r})'
1702+ s = s .format (type (self ).__name__ , self .name , self .rd , self .rs1 )
1703+ return s
1704+
1705+ def __str__ (self ):
1706+ s = '{} {}, {}'
1707+ s = s .format (self .name , self .rd , self .rs1 )
1708+ return s
1709+
1710+ def args (self ):
1711+ return [self .rd , self .rs1 ]
1712+
1713+
16651714# custom syntax for: ecall, ebreak, fence.i
16661715class IETypeInstruction (Instruction ):
16671716
@@ -2361,6 +2410,13 @@ def parse_item(line_tokens):
23612410 name , rd , rs1 , rs2 = tokens
23622411 name = name .lower ()
23632412 return RTypeInstruction (line , name , rd , rs1 , rs2 )
2413+ # rp-type instructions
2414+ elif head in RP_TYPE_INSTRUCTIONS :
2415+ if len (tokens ) != 3 :
2416+ raise AssemblerError ('rp-type instructions require exactly 2 args' , line )
2417+ name , rs1 , rs2 = tokens
2418+ name = name .lower ()
2419+ return RPTypeInstruction (line , name , rs1 , rs2 )
23642420 # i-type instructions
23652421 elif head in I_TYPE_INSTRUCTIONS :
23662422 # check for jalr PI
@@ -2376,6 +2432,13 @@ def parse_item(line_tokens):
23762432 name = name .lower ()
23772433 imm = parse_immediate (imm , line )
23782434 return ITypeInstruction (line , name , rd , rs1 , imm )
2435+ # ip-type instructions
2436+ elif head in IP_TYPE_INSTRUCTIONS :
2437+ if len (tokens ) != 3 :
2438+ raise AssemblerError ('ip-type instructions require exactly 2 args' , line )
2439+ name , rd , rs1 = tokens
2440+ name = name .lower ()
2441+ return IPTypeInstruction (line , name , rd , rs1 )
23792442 # ie-type instructions
23802443 elif head in IE_TYPE_INSTRUCTIONS :
23812444 name , = tokens
@@ -2567,7 +2630,6 @@ def parse_item(line_tokens):
25672630 imm = ['%offset' , reference ]
25682631 imm = parse_immediate (imm , line )
25692632 return CJTypeInstruction (line , name , imm )
2570-
25712633 # pseudo instructions
25722634 elif head in PSEUDO_INSTRUCTIONS :
25732635 name , * args = tokens
0 commit comments