@@ -14,7 +14,10 @@ pub mod lower;
1414#[ cfg( test) ]
1515mod tests;
1616
17- use std:: fmt:: { self , Debug , Display , Formatter } ;
17+ use std:: {
18+ fmt:: { self , Debug , Display , Formatter } ,
19+ ops:: Deref ,
20+ } ;
1821
1922use parser:: { BuiltinFunction , Command , Redirection } ;
2023
@@ -41,13 +44,13 @@ pub enum Instruction {
4144 Negation { dest : Reg , arg : Arg , ty : ArgTy } ,
4245 ToInt { dest : Reg , arg : Arg , ty : ArgTy } ,
4346 Negative { dest : Reg , arg : Arg , ty : ArgTy } ,
44- IncrementPost { dest : Reg , arg : Arg , ty : ArgTy } ,
45- DecrementPost { dest : Reg , arg : Arg , ty : ArgTy } ,
46- IncrementPre { dest : Reg , arg : Arg , ty : ArgTy } ,
47- DecrementPre { dest : Reg , arg : Arg , ty : ArgTy } ,
47+ IncrementPost { dest : Reg , arg : Arg , ty : PlaceTy } ,
48+ DecrementPost { dest : Reg , arg : Arg , ty : PlaceTy } ,
49+ IncrementPre { dest : Reg , arg : Arg , ty : PlaceTy } ,
50+ DecrementPre { dest : Reg , arg : Arg , ty : PlaceTy } ,
4851 CopyP { dest : Reg , arg : Arg , ty : ArgTy } ,
4952 CopyS { dest : Reg , arg : Arg , ty : ArgTy } ,
50- CopyA { dest : Reg , arg : Arg , ty : ArgTy } ,
53+ CopyA { dest : Reg , arg : Arg , ty : PlaceTy } ,
5154
5255 // Binary operations
5356 Eq { dest : Reg , lhs : Arg , rhs : Arg , tyr : ArgTy , tyl : ArgTy } ,
@@ -67,11 +70,11 @@ pub enum Instruction {
6770 Concat { dest : Reg , lhs : Arg , rhs : Arg , tyr : ArgTy , tyl : ArgTy } ,
6871
6972 // Intrinsic operations
70- StoreS { dest : Reg , ty_place : ArgTy , var : NonLocal , arg : Arg , ty : ArgTy } ,
73+ StoreS { dest : Reg , ty_place : PlaceTy , var : NonLocal , arg : Arg , ty : ArgTy } ,
7174 StoreR { dest : Reg , src : Arg , arg : Arg , ty : ArgTy , tys : ArgTy } ,
72- StoreA { dest : Reg , lhs : Arg , rhs : Arg , start : Reg , end : Reg , tyl : ArgTy , tyr : ArgTy } ,
73- LoadA { dest : Reg , arg : Arg , start : Reg , end : Reg , ty : ArgTy } ,
74- LoadM { dest : Reg , arg : Arg , start : Reg , end : Reg , ty : ArgTy } ,
75+ StoreA { dest : Reg , lhs : Arg , rhs : Arg , start : Reg , end : Reg , tyl : PlaceTy , tyr : ArgTy } ,
76+ LoadA { dest : Reg , arg : Arg , start : Reg , end : Reg , ty : PlaceTy } ,
77+ LoadM { dest : Reg , arg : Arg , start : Reg , end : Reg , ty : PlaceTy } ,
7578 IntrinsicCall { dest : Reg , start : Reg , end : Reg , fun : BuiltinFunction } ,
7679 OutputCall { start : Reg , end : Reg , cmd : Command , redir : Option < Redirection > } ,
7780 UserCall { dest : Reg , start : Reg , end : Reg , name : NonLocal } ,
@@ -106,6 +109,7 @@ pub union Arg {
106109}
107110
108111#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
112+ #[ repr( u8 ) ]
109113pub enum ArgTy {
110114 Reg ,
111115 Imm ,
@@ -117,6 +121,22 @@ pub enum ArgTy {
117121 IaVal ,
118122}
119123
124+ #[ derive( Clone , Copy ) ]
125+ #[ repr( u8 ) ]
126+ pub enum PlaceTy {
127+ Reg = ArgTy :: Reg as u8 ,
128+ Rec = ArgTy :: Rec as u8 ,
129+ UsVal = ArgTy :: UsVal as u8 ,
130+ UaVal = ArgTy :: UaVal as u8 ,
131+ IsVal = ArgTy :: IsVal as u8 ,
132+ IaVal = ArgTy :: IaVal as u8 ,
133+ }
134+
135+ const _: ( ) = {
136+ assert ! ( size_of:: <PlaceTy >( ) == size_of:: <ArgTy >( ) ) ;
137+ assert ! ( align_of:: <PlaceTy >( ) == align_of:: <ArgTy >( ) ) ;
138+ } ;
139+
120140impl Instruction {
121141 fn set_label ( & mut self , label : Label ) {
122142 match self {
@@ -187,6 +207,48 @@ impl Instruction {
187207 }
188208}
189209
210+ impl From < PlaceTy > for ArgTy {
211+ #[ inline( always) ]
212+ fn from ( value : PlaceTy ) -> Self {
213+ match value {
214+ PlaceTy :: Reg => Self :: Reg ,
215+ PlaceTy :: Rec => Self :: Rec ,
216+ PlaceTy :: UsVal => Self :: UsVal ,
217+ PlaceTy :: UaVal => Self :: UaVal ,
218+ PlaceTy :: IsVal => Self :: IsVal ,
219+ PlaceTy :: IaVal => Self :: IaVal ,
220+ }
221+ }
222+ }
223+
224+ /// Deref polymorphism is not _that_ bad.
225+ impl Deref for PlaceTy {
226+ type Target = ArgTy ;
227+
228+ #[ inline( always) ]
229+ fn deref ( & self ) -> & Self :: Target {
230+ // SAFETY: The target is declared as a strict superset with equal repr.
231+ unsafe { & * ( & raw const * self ) . cast :: < Self :: Target > ( ) }
232+ }
233+ }
234+
235+ impl TryFrom < ArgTy > for PlaceTy {
236+ type Error = ( ) ;
237+
238+ #[ inline( always) ]
239+ fn try_from ( value : ArgTy ) -> Result < Self , Self :: Error > {
240+ match value {
241+ ArgTy :: Rec => Ok ( Self :: Rec ) ,
242+ ArgTy :: Reg => Ok ( Self :: Reg ) ,
243+ ArgTy :: UsVal => Ok ( Self :: UsVal ) ,
244+ ArgTy :: UaVal => Ok ( Self :: UaVal ) ,
245+ ArgTy :: IsVal => Ok ( Self :: IsVal ) ,
246+ ArgTy :: IaVal => Ok ( Self :: IaVal ) ,
247+ _ => Err ( ( ) ) ,
248+ }
249+ }
250+ }
251+
190252impl Debug for Instruction {
191253 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
192254 write ! ( f, "0x{:032x}" , self . to_bytes( ) )
@@ -207,11 +269,14 @@ impl Display for Instruction {
207269 | Self :: ToInt { dest, arg, ty }
208270 | Self :: Negative { dest, arg, ty }
209271 | Self :: CopyS { dest, arg, ty }
210- | Self :: CopyA { dest, arg, ty }
211272 | Self :: CopyP { dest, arg, ty } => {
212273 write ! ( f, "{dest} <- {op}" ) ?;
213274 fmt_arg ( f, arg, ty, " " )
214275 }
276+ Self :: CopyA { dest, arg, ty } => {
277+ write ! ( f, "{dest} <- {op}" ) ?;
278+ fmt_arg ( f, arg, ty, " " )
279+ }
215280 Self :: Eq { dest, lhs, rhs, tyl, tyr }
216281 | Self :: NEq { dest, lhs, rhs, tyl, tyr }
217282 | Self :: Gt { dest, lhs, rhs, tyl, tyr }
@@ -232,6 +297,7 @@ impl Display for Instruction {
232297 fmt_arg ( f, rhs, tyr, ", " )
233298 }
234299 Self :: StoreS { dest, ty_place, var, arg, ty } => {
300+ let ty_place = ArgTy :: from ( * ty_place) ;
235301 write ! ( f, "{dest} <- {op} {ty_place}({var})" ) ?;
236302 fmt_arg ( f, arg, ty, ", " )
237303 }
0 commit comments