aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/juicebox_asm/lib.rs.html
diff options
context:
space:
mode:
authorjohannst <johannst@users.noreply.github.com>2023-03-05 20:47:28 +0000
committerjohannst <johannst@users.noreply.github.com>2023-03-05 20:47:28 +0000
commit865c1d3231fd57c648121d961be91793d0bfe690 (patch)
treea9dc81103d1e9d38b6a7ffe1f728d5f0e4959610 /src/juicebox_asm/lib.rs.html
parent872cf6d06f4d77637b4627fdc583bab79ee2372f (diff)
downloadjuicebox-asm-865c1d3231fd57c648121d961be91793d0bfe690.tar.gz
juicebox-asm-865c1d3231fd57c648121d961be91793d0bfe690.zip
deploy: 1ea7de2ba46b58b4afe3e65b95d8a45160218a5c
Diffstat (limited to 'src/juicebox_asm/lib.rs.html')
-rw-r--r--src/juicebox_asm/lib.rs.html286
1 files changed, 249 insertions, 37 deletions
diff --git a/src/juicebox_asm/lib.rs.html b/src/juicebox_asm/lib.rs.html
index 7b17af1..47e6bf6 100644
--- a/src/juicebox_asm/lib.rs.html
+++ b/src/juicebox_asm/lib.rs.html
@@ -302,26 +302,214 @@
<a href="#302" id="302">302</a>
<a href="#303" id="303">303</a>
<a href="#304" id="304">304</a>
-</pre><pre class="rust"><code><span class="kw">pub mod </span>prelude;
-<span class="kw">pub mod </span>rt;
+<a href="#305" id="305">305</a>
+<a href="#306" id="306">306</a>
+<a href="#307" id="307">307</a>
+<a href="#308" id="308">308</a>
+<a href="#309" id="309">309</a>
+<a href="#310" id="310">310</a>
+<a href="#311" id="311">311</a>
+<a href="#312" id="312">312</a>
+<a href="#313" id="313">313</a>
+<a href="#314" id="314">314</a>
+<a href="#315" id="315">315</a>
+<a href="#316" id="316">316</a>
+<a href="#317" id="317">317</a>
+<a href="#318" id="318">318</a>
+<a href="#319" id="319">319</a>
+<a href="#320" id="320">320</a>
+<a href="#321" id="321">321</a>
+<a href="#322" id="322">322</a>
+<a href="#323" id="323">323</a>
+<a href="#324" id="324">324</a>
+<a href="#325" id="325">325</a>
+<a href="#326" id="326">326</a>
+<a href="#327" id="327">327</a>
+<a href="#328" id="328">328</a>
+<a href="#329" id="329">329</a>
+<a href="#330" id="330">330</a>
+<a href="#331" id="331">331</a>
+<a href="#332" id="332">332</a>
+<a href="#333" id="333">333</a>
+<a href="#334" id="334">334</a>
+<a href="#335" id="335">335</a>
+<a href="#336" id="336">336</a>
+<a href="#337" id="337">337</a>
+<a href="#338" id="338">338</a>
+<a href="#339" id="339">339</a>
+<a href="#340" id="340">340</a>
+<a href="#341" id="341">341</a>
+<a href="#342" id="342">342</a>
+<a href="#343" id="343">343</a>
+<a href="#344" id="344">344</a>
+<a href="#345" id="345">345</a>
+<a href="#346" id="346">346</a>
+<a href="#347" id="347">347</a>
+<a href="#348" id="348">348</a>
+<a href="#349" id="349">349</a>
+<a href="#350" id="350">350</a>
+<a href="#351" id="351">351</a>
+<a href="#352" id="352">352</a>
+<a href="#353" id="353">353</a>
+<a href="#354" id="354">354</a>
+<a href="#355" id="355">355</a>
+<a href="#356" id="356">356</a>
+<a href="#357" id="357">357</a>
+<a href="#358" id="358">358</a>
+<a href="#359" id="359">359</a>
+<a href="#360" id="360">360</a>
+<a href="#361" id="361">361</a>
+<a href="#362" id="362">362</a>
+<a href="#363" id="363">363</a>
+<a href="#364" id="364">364</a>
+<a href="#365" id="365">365</a>
+<a href="#366" id="366">366</a>
+<a href="#367" id="367">367</a>
+<a href="#368" id="368">368</a>
+<a href="#369" id="369">369</a>
+<a href="#370" id="370">370</a>
+<a href="#371" id="371">371</a>
+<a href="#372" id="372">372</a>
+<a href="#373" id="373">373</a>
+<a href="#374" id="374">374</a>
+<a href="#375" id="375">375</a>
+<a href="#376" id="376">376</a>
+<a href="#377" id="377">377</a>
+<a href="#378" id="378">378</a>
+<a href="#379" id="379">379</a>
+<a href="#380" id="380">380</a>
+<a href="#381" id="381">381</a>
+<a href="#382" id="382">382</a>
+<a href="#383" id="383">383</a>
+<a href="#384" id="384">384</a>
+<a href="#385" id="385">385</a>
+<a href="#386" id="386">386</a>
+<a href="#387" id="387">387</a>
+<a href="#388" id="388">388</a>
+<a href="#389" id="389">389</a>
+<a href="#390" id="390">390</a>
+<a href="#391" id="391">391</a>
+<a href="#392" id="392">392</a>
+<a href="#393" id="393">393</a>
+<a href="#394" id="394">394</a>
+<a href="#395" id="395">395</a>
+<a href="#396" id="396">396</a>
+<a href="#397" id="397">397</a>
+<a href="#398" id="398">398</a>
+<a href="#399" id="399">399</a>
+<a href="#400" id="400">400</a>
+<a href="#401" id="401">401</a>
+<a href="#402" id="402">402</a>
+<a href="#403" id="403">403</a>
+<a href="#404" id="404">404</a>
+<a href="#405" id="405">405</a>
+<a href="#406" id="406">406</a>
+<a href="#407" id="407">407</a>
+<a href="#408" id="408">408</a>
+<a href="#409" id="409">409</a>
+<a href="#410" id="410">410</a>
+</pre><pre class="rust"><code><span class="doccomment">//! A simple `x64` jit assembler with a minimal runtime to execute emitted code for fun.
+//!
+//! The following is an fibonacci example implementation.
+//! ```rust
+//! use juicebox_asm::prelude::*;
+//! use juicebox_asm::Runtime;
+//!
+//! const fn fib_rs(n: u64) -&gt; u64 {
+//! match n {
+//! 0 =&gt; 0,
+//! 1 =&gt; 1,
+//! _ =&gt; fib_rs(n - 2) + fib_rs(n - 1),
+//! }
+//! }
+//!
+//! fn main() {
+//! let mut asm = Asm::new();
+//!
+//! let mut lp = Label::new();
+//! let mut end = Label::new();
+//!
+//! // Reference implementation:
+//! //
+//! // int fib(int n) {
+//! // int tmp = 0;
+//! // int prv = 1;
+//! // int sum = 0;
+//! // loop:
+//! // if (n == 0) goto end;
+//! // tmp = sum;
+//! // sum += prv;
+//! // prv = tmp;
+//! // --n;
+//! // goto loop;
+//! // end:
+//! // return sum;
+//! // }
+//!
+//! // SystemV abi:
+//! // rdi -&gt; first argument
+//! // rax -&gt; return value
+//! let n = Reg64::rdi;
+//! let sum = Reg64::rax;
+//!
+//! let tmp = Reg64::rcx;
+//! let prv = Reg64::rbx;
+//!
+//! asm.mov(tmp, Imm64::from(0));
+//! asm.mov(prv, Imm64::from(1));
+//! asm.mov(sum, Imm64::from(0));
+//!
+//! asm.bind(&amp;mut lp);
+//! asm.test(n, n);
+//! asm.jz(&amp;mut end);
+//! asm.mov(tmp, sum);
+//! asm.add(sum, prv);
+//! asm.mov(prv, tmp);
+//! asm.dec(n);
+//! asm.jmp(&amp;mut lp);
+//! asm.bind(&amp;mut end);
+//! asm.ret();
+//!
+//! // Move code into executable page and get function pointer to it.
+//! let rt = Runtime::new(&amp;asm.into_code());
+//! let fib = unsafe { rt.as_fn::&lt;extern &quot;C&quot; fn(u64) -&gt; u64&gt;() };
+//!
+//! for n in 0..15 {
+//! let fib_jit = fib(n);
+//! println!(&quot;fib({}) = {}&quot;, n, fib_jit);
+//! assert_eq!(fib_jit, fib_rs(n));
+//! }
+//! }
+//! ```
+
+</span><span class="kw">pub mod </span>prelude;
<span class="kw">mod </span>imm;
<span class="kw">mod </span>insn;
<span class="kw">mod </span>label;
<span class="kw">mod </span>reg;
+<span class="kw">mod </span>rt;
+
+<span class="kw">pub use </span>imm::{Imm16, Imm32, Imm64, Imm8};
+<span class="kw">pub use </span>label::Label;
+<span class="kw">pub use </span>reg::{Reg16, Reg32, Reg64, Reg8};
+<span class="kw">pub use </span>rt::Runtime;
<span class="kw">use </span>imm::Imm;
-<span class="kw">use </span>label::Label;
<span class="kw">use </span>reg::Reg;
-<span class="kw">use </span>reg::{Reg16, Reg32, Reg64, Reg8};
-<span class="kw">pub enum </span>MemOp {
- Indirect(Reg64),
- IndirectDisp(Reg64, i32),
+<span class="doccomment">/// Type representing a memory operand.
+</span><span class="kw">pub enum </span>MemOp {
+ <span class="doccomment">/// An indirect memory operand, eg `mov [rax], rcx`.
+ </span>Indirect(Reg64),
+
+ <span class="doccomment">/// An indirect memory operand with additional displacement, eg `mov [rax + 0x10], rcx`.
+ </span>IndirectDisp(Reg64, i32),
}
<span class="kw">impl </span>MemOp {
- <span class="kw">const fn </span>base(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Reg64 {
+ <span class="doccomment">/// Get the base address register of the memory operand.
+ </span><span class="kw">const fn </span>base(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Reg64 {
<span class="kw">match </span><span class="self">self </span>{
MemOp::Indirect(base) =&gt; <span class="kw-2">*</span>base,
MemOp::IndirectDisp(base, ..) =&gt; <span class="kw-2">*</span>base,
@@ -343,31 +531,42 @@
((mod_ &amp; <span class="number">0b11</span>) &lt;&lt; <span class="number">6</span>) | ((reg &amp; <span class="number">0b111</span>) &lt;&lt; <span class="number">3</span>) | (rm &amp; <span class="number">0b111</span>)
}
-<span class="kw">pub struct </span>Asm {
+<span class="doccomment">/// `x64` jit assembler.
+</span><span class="kw">pub struct </span>Asm {
buf: Vec&lt;u8&gt;,
}
<span class="kw">impl </span>Asm {
- <span class="kw">pub fn </span>new() -&gt; Asm {
- <span class="kw">let </span>buf = Vec::with_capacity(<span class="number">1024</span>);
+ <span class="doccomment">/// Create a new `x64` jit assembler.
+ </span><span class="kw">pub fn </span>new() -&gt; Asm {
+ <span class="comment">// Some random default capacity.
+ </span><span class="kw">let </span>buf = Vec::with_capacity(<span class="number">1024</span>);
Asm { buf }
}
- <span class="kw">pub fn </span>into_code(<span class="self">self</span>) -&gt; Vec&lt;u8&gt; {
+ <span class="doccomment">/// Consume the assembler and get the emitted code.
+ </span><span class="kw">pub fn </span>into_code(<span class="self">self</span>) -&gt; Vec&lt;u8&gt; {
<span class="self">self</span>.buf
}
- <span class="kw">fn </span>emit(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bytes: <span class="kw-2">&amp;</span>[u8]) {
+ <span class="doccomment">/// Emit a slice of bytes.
+ </span><span class="kw">fn </span>emit(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bytes: <span class="kw-2">&amp;</span>[u8]) {
<span class="self">self</span>.buf.extend_from_slice(bytes);
}
- <span class="kw">fn </span>emit_optional(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bytes: <span class="kw-2">&amp;</span>[<span class="prelude-ty">Option</span>&lt;u8&gt;]) {
+ <span class="doccomment">/// Emit a slice of optional bytes.
+ </span><span class="kw">fn </span>emit_optional(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bytes: <span class="kw-2">&amp;</span>[<span class="prelude-ty">Option</span>&lt;u8&gt;]) {
<span class="kw">for </span>byte <span class="kw">in </span>bytes.iter().filter_map(|<span class="kw-2">&amp;</span>b| b) {
<span class="self">self</span>.buf.push(byte);
}
}
- <span class="kw">fn </span>emit_at(<span class="kw-2">&amp;mut </span><span class="self">self</span>, pos: usize, bytes: <span class="kw-2">&amp;</span>[u8]) {
+ <span class="doccomment">/// Emit a slice of bytes at `pos`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if [pos..pos+len] indexes out of bound of the underlying code buffer.
+ </span><span class="kw">fn </span>emit_at(<span class="kw-2">&amp;mut </span><span class="self">self</span>, pos: usize, bytes: <span class="kw-2">&amp;</span>[u8]) {
<span class="kw">if let </span><span class="prelude-val">Some</span>(buf) = <span class="self">self</span>.buf.get_mut(pos..pos + bytes.len()) {
buf.copy_from_slice(bytes);
} <span class="kw">else </span>{
@@ -387,7 +586,8 @@
<span class="doccomment">/// If the [Label] is bound, patch any pending relocation.
</span><span class="kw">pub fn </span>resolve(<span class="kw-2">&amp;mut </span><span class="self">self</span>, label: <span class="kw-2">&amp;mut </span>Label) {
<span class="kw">if let </span><span class="prelude-val">Some</span>(loc) = label.location() {
- <span class="kw">let </span>loc = i32::try_from(loc).expect(<span class="string">&quot;Label location did not fit into i32.&quot;</span>);
+ <span class="comment">// For now we only support disp32 as label location.
+ </span><span class="kw">let </span>loc = i32::try_from(loc).expect(<span class="string">&quot;Label location did not fit into i32.&quot;</span>);
<span class="comment">// Resolve any pending relocations for the label.
</span><span class="kw">for </span>off <span class="kw">in </span>label.offsets_mut().drain() {
@@ -404,6 +604,7 @@
<span class="comment">// -- Encode utilities.
+ </span><span class="doccomment">/// Encode an register-register instruction.
</span><span class="kw">fn </span>encode_rr&lt;T: Reg&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, op1: T, op2: T)
<span class="kw">where
</span><span class="self">Self</span>: EncodeRR&lt;T&gt;,
@@ -424,22 +625,25 @@
<span class="self">self</span>.emit(<span class="kw-2">&amp;</span>[opc, modrm]);
}
- <span class="kw">fn </span>encode_oi&lt;T: Reg, U: Imm&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, op1: T, op2: U)
+ <span class="doccomment">/// Encode an offset-immediate instruction.
+ /// Register idx is encoded in the opcode.
+ </span><span class="kw">fn </span>encode_oi&lt;T: Reg, U: Imm&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, op1: T, op2: U)
<span class="kw">where
- </span><span class="self">Self</span>: EncodeRI&lt;T&gt;,
+ </span><span class="self">Self</span>: EncodeR&lt;T&gt;,
{
<span class="kw">let </span>opc = opc + (op1.idx() &amp; <span class="number">0b111</span>);
- <span class="kw">let </span>prefix = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeRI&lt;T&gt;&gt;::legacy_prefix();
- <span class="kw">let </span>rex = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeRI&lt;T&gt;&gt;::rex(op1);
+ <span class="kw">let </span>prefix = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeR&lt;T&gt;&gt;::legacy_prefix();
+ <span class="kw">let </span>rex = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeR&lt;T&gt;&gt;::rex(op1);
<span class="self">self</span>.emit_optional(<span class="kw-2">&amp;</span>[prefix, rex]);
<span class="self">self</span>.emit(<span class="kw-2">&amp;</span>[opc]);
<span class="self">self</span>.emit(op2.bytes());
}
- <span class="kw">fn </span>encode_ri&lt;T: Reg, U: Imm&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, opc_ext: u8, op1: T, op2: U)
+ <span class="doccomment">/// Encode a register-immediate instruction.
+ </span><span class="kw">fn </span>encode_ri&lt;T: Reg, U: Imm&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, opc_ext: u8, op1: T, op2: U)
<span class="kw">where
- </span><span class="self">Self</span>: EncodeRI&lt;T&gt;,
+ </span><span class="self">Self</span>: EncodeR&lt;T&gt;,
{
<span class="comment">// MI operand encoding.
// op1 -&gt; modrm.rm
@@ -450,17 +654,18 @@
</span>op1.idx(), <span class="comment">/* rm */
</span>);
- <span class="kw">let </span>prefix = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeRI&lt;T&gt;&gt;::legacy_prefix();
- <span class="kw">let </span>rex = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeRI&lt;T&gt;&gt;::rex(op1);
+ <span class="kw">let </span>prefix = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeR&lt;T&gt;&gt;::legacy_prefix();
+ <span class="kw">let </span>rex = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeR&lt;T&gt;&gt;::rex(op1);
<span class="self">self</span>.emit_optional(<span class="kw-2">&amp;</span>[prefix, rex]);
<span class="self">self</span>.emit(<span class="kw-2">&amp;</span>[opc, modrm]);
<span class="self">self</span>.emit(op2.bytes());
}
- <span class="kw">fn </span>encode_r&lt;T: Reg&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, opc_ext: u8, op1: T)
+ <span class="doccomment">/// Encode a register instruction.
+ </span><span class="kw">fn </span>encode_r&lt;T: Reg&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, opc_ext: u8, op1: T)
<span class="kw">where
- </span><span class="self">Self</span>: EncodeRI&lt;T&gt;,
+ </span><span class="self">Self</span>: EncodeR&lt;T&gt;,
{
<span class="comment">// M operand encoding.
// op1 -&gt; modrm.rm
@@ -471,14 +676,15 @@
</span>op1.idx(), <span class="comment">/* rm */
</span>);
- <span class="kw">let </span>prefix = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeRI&lt;T&gt;&gt;::legacy_prefix();
- <span class="kw">let </span>rex = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeRI&lt;T&gt;&gt;::rex(op1);
+ <span class="kw">let </span>prefix = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeR&lt;T&gt;&gt;::legacy_prefix();
+ <span class="kw">let </span>rex = &lt;<span class="self">Self </span><span class="kw">as </span>EncodeR&lt;T&gt;&gt;::rex(op1);
<span class="self">self</span>.emit_optional(<span class="kw-2">&amp;</span>[prefix, rex]);
<span class="self">self</span>.emit(<span class="kw-2">&amp;</span>[opc, modrm]);
}
- <span class="kw">fn </span>encode_mr&lt;T: Reg&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, op1: MemOp, op2: T)
+ <span class="doccomment">/// Encode a memory-register instruction.
+ </span><span class="kw">fn </span>encode_mr&lt;T: Reg&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, op1: MemOp, op2: T)
<span class="kw">where
</span><span class="self">Self</span>: EncodeMR&lt;T&gt;,
{
@@ -511,7 +717,8 @@
}
}
- <span class="kw">fn </span>encode_rm&lt;T: Reg&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, op1: T, op2: MemOp)
+ <span class="doccomment">/// Encode a register-memory instruction.
+ </span><span class="kw">fn </span>encode_rm&lt;T: Reg&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: u8, op1: T, op2: MemOp)
<span class="kw">where
</span><span class="self">Self</span>: EncodeMR&lt;T&gt;,
{
@@ -521,7 +728,8 @@
</span><span class="self">self</span>.encode_mr(opc, op2, op1);
}
- <span class="kw">fn </span>encode_jmp_label(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: <span class="kw-2">&amp;</span>[u8], op1: <span class="kw-2">&amp;mut </span>Label) {
+ <span class="doccomment">/// Encode a jump to label instruction.
+ </span><span class="kw">fn </span>encode_jmp_label(<span class="kw-2">&amp;mut </span><span class="self">self</span>, opc: <span class="kw-2">&amp;</span>[u8], op1: <span class="kw-2">&amp;mut </span>Label) {
<span class="comment">// Emit the opcode.
</span><span class="self">self</span>.emit(opc);
@@ -529,6 +737,7 @@
</span>op1.record_offset(<span class="self">self</span>.buf.len());
<span class="comment">// Emit a zeroed disp32, which serves as placeholder for the relocation.
+ // We currently only support disp32 jump targets.
</span><span class="self">self</span>.emit(<span class="kw-2">&amp;</span>[<span class="number">0u8</span>; <span class="number">4</span>]);
<span class="comment">// Resolve any pending relocations for the label.
@@ -538,6 +747,7 @@
<span class="comment">// -- Encoder helper.
+</span><span class="doccomment">/// Encode helper for register-register instructions.
</span><span class="kw">trait </span>EncodeRR&lt;T: Reg&gt; {
<span class="kw">fn </span>legacy_prefix() -&gt; <span class="prelude-ty">Option</span>&lt;u8&gt; {
<span class="prelude-val">None
@@ -561,7 +771,8 @@
}
<span class="kw">impl </span>EncodeRR&lt;Reg64&gt; <span class="kw">for </span>Asm {}
-<span class="kw">trait </span>EncodeRI&lt;T: Reg&gt; {
+<span class="doccomment">/// Encode helper for register instructions.
+</span><span class="kw">trait </span>EncodeR&lt;T: Reg&gt; {
<span class="kw">fn </span>legacy_prefix() -&gt; <span class="prelude-ty">Option</span>&lt;u8&gt; {
<span class="prelude-val">None
</span>}
@@ -575,16 +786,17 @@
}
}
-<span class="kw">impl </span>EncodeRI&lt;Reg8&gt; <span class="kw">for </span>Asm {}
-<span class="kw">impl </span>EncodeRI&lt;Reg32&gt; <span class="kw">for </span>Asm {}
-<span class="kw">impl </span>EncodeRI&lt;Reg16&gt; <span class="kw">for </span>Asm {
+<span class="kw">impl </span>EncodeR&lt;Reg8&gt; <span class="kw">for </span>Asm {}
+<span class="kw">impl </span>EncodeR&lt;Reg32&gt; <span class="kw">for </span>Asm {}
+<span class="kw">impl </span>EncodeR&lt;Reg16&gt; <span class="kw">for </span>Asm {
<span class="kw">fn </span>legacy_prefix() -&gt; <span class="prelude-ty">Option</span>&lt;u8&gt; {
<span class="prelude-val">Some</span>(<span class="number">0x66</span>)
}
}
-<span class="kw">impl </span>EncodeRI&lt;Reg64&gt; <span class="kw">for </span>Asm {}
+<span class="kw">impl </span>EncodeR&lt;Reg64&gt; <span class="kw">for </span>Asm {}
-<span class="kw">trait </span>EncodeMR&lt;T: Reg&gt; {
+<span class="doccomment">/// Encode helper for memory-register instructions.
+</span><span class="kw">trait </span>EncodeMR&lt;T: Reg&gt; {
<span class="kw">fn </span>legacy_prefix() -&gt; <span class="prelude-ty">Option</span>&lt;u8&gt; {
<span class="prelude-val">None
</span>}