Skip to content

Commit 9cafeaf

Browse files
committed
Latest
1 parent 17d17a8 commit 9cafeaf

File tree

1 file changed

+76
-59
lines changed

1 file changed

+76
-59
lines changed

workspace/assembler/src/mk2/OrdinaryInstructionStream.rs

+76-59
Original file line numberDiff line numberDiff line change
@@ -24,66 +24,92 @@ impl OrdinaryInstructionStream
2424
/// `REX` prefix.
2525
pub(crate) const REX: u8 = 0x40;
2626

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).
2738
#[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)
2940
{
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
6045
}
61-
}
46+
else
47+
{
48+
0x40
49+
};
6250

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+
};
6959

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)
7467
}
7568
}
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;
7675

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)
8483
}
8584
}
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);
87113
}
88114

89115
#[inline(always)]
@@ -128,15 +154,6 @@ impl OrdinaryInstructionStream
128154
rm.emit_rex_2(&mut self.byte_emitter, byte)
129155
}
130156

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-
140157
#[inline(always)]
141158
fn opcode_1(&mut self, opcode: u8)
142159
{

0 commit comments

Comments
 (0)