@@ -34,13 +34,12 @@ pub fn fmt(
3434/// This function panics if the location is an immediate (i.e., an immediate
3535/// cannot be written to).
3636#[ must_use]
37- pub fn rw ( location : Location ) -> Operand {
38- assert ! ( !matches!( location. kind( ) , OperandKind :: Imm ( _) ) ) ;
37+ pub fn rw ( op : impl Into < Operand > ) -> Operand {
38+ let op = op. into ( ) ;
39+ assert ! ( !matches!( op. location. kind( ) , OperandKind :: Imm ( _) ) ) ;
3940 Operand {
40- location,
4141 mutability : Mutability :: ReadWrite ,
42- extension : Extension :: default ( ) ,
43- align : false ,
42+ ..op
4443 }
4544}
4645
@@ -54,23 +53,30 @@ pub fn r(op: impl Into<Operand>) -> Operand {
5453
5554/// An abbreviated constructor for a "write" operand.
5655#[ must_use]
57- pub fn w ( location : Location ) -> Operand {
56+ pub fn w ( op : impl Into < Operand > ) -> Operand {
57+ let op = op. into ( ) ;
5858 Operand {
59- location,
6059 mutability : Mutability :: Write ,
61- extension : Extension :: None ,
62- align : false ,
60+ ..op
6361 }
6462}
6563
6664/// An abbreviated constructor for a memory operand that requires alignment.
6765pub fn align ( location : Location ) -> Operand {
6866 assert ! ( location. uses_memory( ) ) ;
6967 Operand {
70- location,
71- mutability : Mutability :: Read ,
72- extension : Extension :: None ,
7368 align : true ,
69+ ..Operand :: from ( location)
70+ }
71+ }
72+
73+ /// An abbreviated constructor for an operand that is used by the instruction
74+ /// but not visible in its disassembly.
75+ pub fn implicit ( location : Location ) -> Operand {
76+ assert ! ( matches!( location. kind( ) , OperandKind :: FixedReg ( _) ) ) ;
77+ Operand {
78+ implicit : true ,
79+ ..Operand :: from ( location)
7480 }
7581}
7682
@@ -84,10 +90,8 @@ pub fn align(location: Location) -> Operand {
8490pub fn sxq ( location : Location ) -> Operand {
8591 assert ! ( location. bits( ) <= 64 ) ;
8692 Operand {
87- location,
88- mutability : Mutability :: Read ,
8993 extension : Extension :: SignExtendQuad ,
90- align : false ,
94+ .. Operand :: from ( location )
9195 }
9296}
9397
@@ -101,10 +105,8 @@ pub fn sxq(location: Location) -> Operand {
101105pub fn sxl ( location : Location ) -> Operand {
102106 assert ! ( location. bits( ) <= 32 ) ;
103107 Operand {
104- location,
105- mutability : Mutability :: Read ,
106108 extension : Extension :: SignExtendLong ,
107- align : false ,
109+ .. Operand :: from ( location )
108110 }
109111}
110112
@@ -118,10 +120,8 @@ pub fn sxl(location: Location) -> Operand {
118120pub fn sxw ( location : Location ) -> Operand {
119121 assert ! ( location. bits( ) <= 16 ) ;
120122 Operand {
121- location,
122- mutability : Mutability :: Read ,
123123 extension : Extension :: SignExtendWord ,
124- align : false ,
124+ .. Operand :: from ( location )
125125 }
126126}
127127
@@ -204,6 +204,9 @@ pub struct Operand {
204204 /// address used in the operand must align to the size of the operand (e.g.,
205205 /// `m128` must be 16-byte aligned).
206206 pub align : bool ,
207+ /// Some register operands are implicit: that is, they do not appear in the
208+ /// disassembled output even though they are used in the instruction.
209+ pub implicit : bool ,
207210}
208211
209212impl core:: fmt:: Display for Operand {
@@ -213,6 +216,7 @@ impl core::fmt::Display for Operand {
213216 mutability,
214217 extension,
215218 align,
219+ implicit,
216220 } = self ;
217221 write ! ( f, "{location}" ) ?;
218222 let mut flags = vec ! [ ] ;
@@ -225,6 +229,9 @@ impl core::fmt::Display for Operand {
225229 if * align != false {
226230 flags. push ( "align" . to_owned ( ) ) ;
227231 }
232+ if * implicit {
233+ flags. push ( "implicit" . to_owned ( ) ) ;
234+ }
228235 if !flags. is_empty ( ) {
229236 write ! ( f, "[{}]" , flags. join( "," ) ) ?;
230237 }
@@ -237,11 +244,13 @@ impl From<Location> for Operand {
237244 let mutability = Mutability :: default ( ) ;
238245 let extension = Extension :: default ( ) ;
239246 let align = false ;
247+ let implicit = false ;
240248 Self {
241249 location,
242250 mutability,
243251 extension,
244252 align,
253+ implicit,
245254 }
246255 }
247256}
@@ -270,6 +279,9 @@ pub enum Location {
270279 ax,
271280 eax,
272281 rax,
282+ dx,
283+ edx,
284+ rdx,
273285 cl,
274286
275287 // Immediate values.
@@ -307,9 +319,9 @@ impl Location {
307319 use Location :: * ;
308320 match self {
309321 al | cl | imm8 | r8 | rm8 | m8 => 8 ,
310- ax | imm16 | r16 | rm16 | m16 => 16 ,
311- eax | imm32 | r32 | rm32 | m32 | xmm_m32 => 32 ,
312- rax | r64 | rm64 | m64 | xmm_m64 => 64 ,
322+ ax | dx | imm16 | r16 | rm16 | m16 => 16 ,
323+ eax | edx | imm32 | r32 | rm32 | m32 | xmm_m32 => 32 ,
324+ rax | rdx | r64 | rm64 | m64 | xmm_m64 => 64 ,
313325 xmm | xmm_m128 => 128 ,
314326 }
315327 }
@@ -325,7 +337,8 @@ impl Location {
325337 pub fn uses_memory ( & self ) -> bool {
326338 use Location :: * ;
327339 match self {
328- al | cl | ax | eax | rax | imm8 | imm16 | imm32 | r8 | r16 | r32 | r64 | xmm => false ,
340+ al | ax | eax | rax | cl | dx | edx | rdx | imm8 | imm16 | imm32 | r8 | r16 | r32
341+ | r64 | xmm => false ,
329342 rm8 | rm16 | rm32 | rm64 | xmm_m32 | xmm_m64 | xmm_m128 | m8 | m16 | m32 | m64 => true ,
330343 }
331344 }
@@ -337,8 +350,8 @@ impl Location {
337350 use Location :: * ;
338351 match self {
339352 imm8 | imm16 | imm32 => false ,
340- al | ax | eax | rax | cl | r8 | r16 | r32 | r64 | rm8 | rm16 | rm32 | rm64 | xmm
341- | xmm_m32 | xmm_m64 | xmm_m128 | m8 | m16 | m32 | m64 => true ,
353+ al | ax | eax | rax | cl | dx | edx | rdx | r8 | r16 | r32 | r64 | rm8 | rm16
354+ | rm32 | rm64 | xmm | xmm_m32 | xmm_m64 | xmm_m128 | m8 | m16 | m32 | m64 => true ,
342355 }
343356 }
344357
@@ -347,7 +360,7 @@ impl Location {
347360 pub fn kind ( & self ) -> OperandKind {
348361 use Location :: * ;
349362 match self {
350- al | ax | eax | rax | cl => OperandKind :: FixedReg ( * self ) ,
363+ al | ax | eax | rax | cl | dx | edx | rdx => OperandKind :: FixedReg ( * self ) ,
351364 imm8 | imm16 | imm32 => OperandKind :: Imm ( * self ) ,
352365 r8 | r16 | r32 | r64 | xmm => OperandKind :: Reg ( * self ) ,
353366 rm8 | rm16 | rm32 | rm64 | xmm_m32 | xmm_m64 | xmm_m128 => OperandKind :: RegMem ( * self ) ,
@@ -364,9 +377,8 @@ impl Location {
364377 use Location :: * ;
365378 match self {
366379 imm8 | imm16 | imm32 | m8 | m16 | m32 | m64 => None ,
367- al | ax | eax | rax | cl | r8 | r16 | r32 | r64 | rm8 | rm16 | rm32 | rm64 => {
368- Some ( RegClass :: Gpr )
369- }
380+ al | ax | eax | rax | cl | dx | edx | rdx | r8 | r16 | r32 | r64 | rm8 | rm16
381+ | rm32 | rm64 => Some ( RegClass :: Gpr ) ,
370382 xmm | xmm_m32 | xmm_m64 | xmm_m128 => Some ( RegClass :: Xmm ) ,
371383 }
372384 }
@@ -385,6 +397,9 @@ impl core::fmt::Display for Location {
385397 eax => write ! ( f, "eax" ) ,
386398 rax => write ! ( f, "rax" ) ,
387399 cl => write ! ( f, "cl" ) ,
400+ dx => write ! ( f, "dx" ) ,
401+ edx => write ! ( f, "edx" ) ,
402+ rdx => write ! ( f, "rdx" ) ,
388403
389404 r8 => write ! ( f, "r8" ) ,
390405 r16 => write ! ( f, "r16" ) ,
0 commit comments