@@ -24,66 +24,92 @@ impl OrdinaryInstructionStream
24
24
/// `REX` prefix.
25
25
pub ( crate ) const REX : u8 = 0x40 ;
26
26
27
+
28
+ /*
29
+
30
+ TODO: Now remove redundant arguments like arg0: XMM0, RAX, etc.!
31
+ - Will require us to remove things like RAX::O which are present in the code.
32
+
33
+ TODO: FINISH VEX
34
+
35
+ */
36
+
37
+ // See Figure 2-9, Intel Manual Volume 2A Section 2-15 (May 2018).
27
38
#[ inline( always) ]
28
- fn vex ( & mut self )
39
+ fn vex ( & mut self , mmmmm : u8 , L : u8 , pp : u8 , w : u8 , vvvv : impl Register , rm : Memory , r : impl Register )
29
40
{
30
- /*
31
- /** Emits a 2-byte vex prefix. See Figure 2-9: Intel Manual Vol 2A 2-14. */
32
- void vex2(uint8_t r_bit, const Operand& vvvv, uint8_t l, uint8_t pp) {
33
- fxn_->emit_byte(0xc5);
34
- fxn_->emit_byte(r_bit | ((~vvvv.val_ << 3) & 0x78) | (l << 2) | pp);
35
- }
36
-
37
- /** Emits a 3-byte vex prefix. See Figure 2-9: Intel Manual Vol 2A 2-14. */
38
- void vex3(uint8_t r_bit, uint8_t x_bit, uint8_t b_bit, uint8_t mmmmm,
39
- uint8_t w, const Operand& vvvv, uint8_t l, uint8_t pp) {
40
- fxn_->emit_byte(0xc4);
41
- fxn_->emit_byte(r_bit | x_bit | b_bit | mmmmm);
42
- fxn_->emit_byte((w << 7) | ((~vvvv.val_ << 3) & 0x78) | (l << 2) | pp);
43
- }
44
-
45
- // Emits a vex prefix. See Figure 2-9: Intel Manual Vol 2A 2-14. */
46
- template <typename T >
47
- void vex( uint8_t mmmmm, uint8_t l, uint8_t pp, uint8_t w,
48
- const Operand & vvvv, const M <T >& rm,
49
- const Operand & r) {
50
- uint8_t r_bit = ( ~r. val_ << 4 ) & 0x80 ;
51
- uint8_t x_bit = rm. contains_index ( ) ?
52
- ( ~rm. get_index ( ) . val_ << 3 ) & 0x40 : 0x40 ;
53
- uint8_t b_bit = rm. contains_base ( ) ?
54
- ( ~rm. get_base ( ) . val_ << 2 ) & 0x20 : 0x20 ;
55
-
56
- if ( x_bit == 0x40 && b_bit == 0x20 && mmmmm == 0x01 && w == 0 ) {
57
- vex2 ( r_bit, vvvv, l, pp) ;
58
- } else {
59
- vex3 ( r_bit, x_bit, b_bit, mmmmm, w, vvvv, l, pp) ;
41
+ let r_bit = ( !r. index ( ) << 4 ) & 0x80 ;
42
+ let x_bit = if rm. has_index_register ( )
43
+ {
44
+ ( !rm. get_index ( ) . index ( ) << 3 ) & 0x40
60
45
}
61
- }
46
+ else
47
+ {
48
+ 0x40
49
+ } ;
62
50
63
- /** Emits a vex prefix. See Figure 2-9: Intel Manual Vol 2A 2-14. */
64
- void vex( uint8_t mmmmm, uint8_t l, uint8_t pp, uint8_t w,
65
- const Operand & vvvv, const Operand & rm,
66
- const Operand & r) {
67
- uint8_t r_bit = ( ~r. val_ << 4 ) & 0x80 ;
68
- uint8_t b_bit = ( ~rm. val_ << 2 ) & 0x20 ;
51
+ let b_bit = if rm. has_base_register ( )
52
+ {
53
+ ( !rm. get_base ( ) . index ( ) << 2 ) & 0x20
54
+ }
55
+ else
56
+ {
57
+ 0x20
58
+ } ;
69
59
70
- if ( b_bit == 0x20 && mmmmm == 0x01 && w == 0 ) {
71
- vex2 ( r_bit, vvvv, l, pp) ;
72
- } else {
73
- vex3 ( r_bit, 0x40 , b_bit, mmmmm, w, vvvv, l, pp) ;
60
+ if x_bit == 0x40 && b_bit == 0x20 && mmmmm == 0x01 && w == 0
61
+ {
62
+ self . emit_2_byte_vex_prefix ( r_bit, vvvv, L , pp)
63
+ }
64
+ else
65
+ {
66
+ self . emit_3_byte_vex_prefix ( r_bit, x_bit, b_bit, mmmmm, w, vvvv, L , pp)
74
67
}
75
68
}
69
+
70
+ #[ inline( always) ]
71
+ fn vex ( & mut self , mmmmm : u8 , L : u8 , pp : u8 , w : u8 , vvvv : impl Register , rm : Operand , r : impl Register )
72
+ {
73
+ let r_bit = ( !r. index ( ) << 4 ) & 0x80 ;
74
+ let b_bit = ( !rm. index ( ) << 2 ) & 0x20 ;
76
75
77
- /** Emits a vex prefix. See Figure 2-9: Intel Manual Vol 2A 2-14. */
78
- void vex ( uint8_t mmmmm , uint8_t l , uint8_t pp , uint8_t w ,
79
- const Operand & vvvv) {
80
- if ( mmmmm == 0x01 && w == 0 ) {
81
- vex2 ( 0x80 , vvvv , l , pp ) ;
82
- } else {
83
- vex3 ( 0x80 , 0x40 , 0x20 , mmmmm, w, vvvv, l , pp) ;
76
+ if b_bit == 0x20 && mmmmm == 0x01 && w == 0
77
+ {
78
+ self . emit_2_byte_vex_prefix ( r_bit , vvvv, L , pp )
79
+ }
80
+ else
81
+ {
82
+ self . emit_3_byte_vex_prefix ( r_bit , 0x40 , b_bit , mmmmm, w, vvvv, L , pp)
84
83
}
85
84
}
86
- * /
85
+
86
+ // This form seems to be missing...
87
+ // #[inline(always)]
88
+ // fn vex(&mut self, mmmmm: u8, L: u8, pp: u8, w: u8, vvvv: impl Register)
89
+ // {
90
+ // if mmmmm == 0x01 && w == 0
91
+ // {
92
+ // self.emit_2_byte_vex_prefix(0x80, vvvv, L, pp)
93
+ // }
94
+ // else
95
+ // {
96
+ // self.emit_3_byte_vex_prefix(0x80, 0x40, 0x20, mmmmm, w, vvvv, L, pp)
97
+ // }
98
+ // }
99
+
100
+ #[ inline( always) ]
101
+ fn emit_2_byte_vex_prefix ( & mut self , r_bit : u8 , vvvv : impl Register , l : u8 , pp : u8 )
102
+ {
103
+ self . byte_emitter . emit_u8 ( 0xC5 ) ;
104
+ self . byte_emitter . emit_u8 ( ( r_bit | ( ( !vvvv. index ( ) ) << 3 ) & 0x78 ) | ( l << 2 ) | pp) ;
105
+ }
106
+
107
+ #[ inline( always) ]
108
+ fn emit_3_byte_vex_prefix ( & mut self , r_bit : u8 , x_bit : u8 , b_bit : u8 , mmmmm : u8 , w : u8 , vvvv : impl Register , l : u8 , pp : u8 )
109
+ {
110
+ self . byte_emitter . emit_u8 ( 0xC5 ) ;
111
+ self . byte_emitter . emit_u8 ( r_bit | x_bit | b_bit | mmmmm) ;
112
+ self . byte_emitter . emit_u8 ( ( w << 7 ) | ( ( !vvvv. index ( ) << 3 ) & 0x78 ) | ( l << 2 ) | pp) ;
87
113
}
88
114
89
115
#[ inline( always) ]
@@ -128,15 +154,6 @@ impl OrdinaryInstructionStream
128
154
rm. emit_rex_2 ( & mut self . byte_emitter , byte)
129
155
}
130
156
131
- /*
132
-
133
- TODO: self.vex(0x02, 0x0, 0x0, 0x0, arg1, arg2, arg0);
134
-
135
- TODO: Now remove redundant arguments like arg0: XMM0, RAX, etc.!
136
-
137
- */
138
-
139
-
140
157
#[ inline( always) ]
141
158
fn opcode_1 ( & mut self , opcode : u8 )
142
159
{
0 commit comments