diff options
author | johannst <johannst@users.noreply.github.com> | 2024-12-13 00:18:53 +0000 |
---|---|---|
committer | johannst <johannst@users.noreply.github.com> | 2024-12-13 00:18:53 +0000 |
commit | c94a65c993f5da6a86bd1e6d23e359ba2052f836 (patch) | |
tree | 8ca23ecd01fb4cd26c958e310c3f352cc7c73d63 /src/juicebox_asm/asm.rs.html | |
parent | 741d915aed07eb4ea265d8e90cf64e8ca6552ddc (diff) | |
download | juicebox-asm-c94a65c993f5da6a86bd1e6d23e359ba2052f836.tar.gz juicebox-asm-c94a65c993f5da6a86bd1e6d23e359ba2052f836.zip |
deploy: 758f014afb8ec5c20ef2fc862fc12e80f65d3d25
Diffstat (limited to 'src/juicebox_asm/asm.rs.html')
-rw-r--r-- | src/juicebox_asm/asm.rs.html | 148 |
1 files changed, 67 insertions, 81 deletions
diff --git a/src/juicebox_asm/asm.rs.html b/src/juicebox_asm/asm.rs.html index 3f24ae2..1b159ca 100644 --- a/src/juicebox_asm/asm.rs.html +++ b/src/juicebox_asm/asm.rs.html @@ -450,17 +450,11 @@ <a href="#449" id="449">449</a> <a href="#450" id="450">450</a> <a href="#451" id="451">451</a> -<a href="#452" id="452">452</a> -<a href="#453" id="453">453</a> -<a href="#454" id="454">454</a> -<a href="#455" id="455">455</a> -<a href="#456" id="456">456</a> -<a href="#457" id="457">457</a> -<a href="#458" id="458">458</a> -<a href="#459" id="459">459</a></pre></div><pre class="rust"><code><span class="doccomment">//! The `x64` jit assembler. +<a href="#452" id="452">452</a></pre></div><pre class="rust"><code><span class="doccomment">//! The `x64` jit assembler. </span><span class="kw">use crate</span>::<span class="kw-2">*</span>; <span class="kw">use </span>imm::Imm; +<span class="kw">use </span>mem::{AddrMode, Mem}; <span class="kw">use </span>reg::Reg; <span class="doccomment">/// Encode the `REX` byte. @@ -614,24 +608,22 @@ } <span class="doccomment">/// Encode a memory operand instruction. - </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>encode_m<T: MemOpSized>(<span class="kw-2">&mut </span><span class="self">self</span>, opc: u8, opc_ext: u8, op1: T) + </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>encode_m<T: Mem>(<span class="kw-2">&mut </span><span class="self">self</span>, opc: u8, opc_ext: u8, op1: T) <span class="kw">where </span><span class="self">Self</span>: EncodeM<T>, { - <span class="kw">let </span>op1 = op1.mem_op(); - <span class="comment">// M operand encoding. // op1 -> modrm.rm - </span><span class="kw">let </span>(mode, rm) = <span class="kw">match </span>op1 { - MemOp::Indirect(..) => { + </span><span class="kw">let </span>(mode, rm) = <span class="kw">match </span>op1.mode() { + AddrMode::Indirect => { <span class="macro">assert!</span>(!op1.base().need_sib() && !op1.base().is_pc_rel()); (<span class="number">0b00</span>, op1.base().idx()) } - MemOp::IndirectDisp(..) => { + AddrMode::IndirectDisp => { <span class="macro">assert!</span>(!op1.base().need_sib()); (<span class="number">0b10</span>, op1.base().idx()) } - MemOp::IndirectBaseIndex(..) => { + AddrMode::IndirectBaseIndex => { <span class="macro">assert!</span>(!op1.base().is_pc_rel()); <span class="comment">// Using rsp as index register is interpreted as just base w/o offset. // https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing_2 @@ -652,31 +644,33 @@ <span class="self">self</span>.emit_optional(<span class="kw-2">&</span>[prefix, rex]); <span class="self">self</span>.emit(<span class="kw-2">&</span>[opc, modrm]); - <span class="kw">match </span>op1 { - MemOp::Indirect(..) => {} - MemOp::IndirectDisp(<span class="kw">_</span>, disp) => <span class="self">self</span>.emit(<span class="kw-2">&</span>disp.to_ne_bytes()), - MemOp::IndirectBaseIndex(base, index) => <span class="self">self</span>.emit(<span class="kw-2">&</span>[sib(<span class="number">0</span>, index.idx(), base.idx())]), + <span class="kw">match </span>op1.mode() { + AddrMode::Indirect => {} + AddrMode::IndirectDisp => <span class="self">self</span>.emit(<span class="kw-2">&</span>op1.disp().to_ne_bytes()), + AddrMode::IndirectBaseIndex => { + <span class="self">self</span>.emit(<span class="kw-2">&</span>[sib(<span class="number">0</span>, op1.index().idx(), op1.base().idx())]) + } } } <span class="doccomment">/// Encode a memory-immediate instruction. - </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>encode_mi<T: Imm>(<span class="kw-2">&mut </span><span class="self">self</span>, opc: u8, opc_ext: u8, op1: MemOp, op2: T) + </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>encode_mi<M: Mem, T: Imm>(<span class="kw-2">&mut </span><span class="self">self</span>, opc: u8, opc_ext: u8, op1: M, op2: T) <span class="kw">where - </span><span class="self">Self</span>: EncodeMI<T>, + </span><span class="self">Self</span>: EncodeMI<M>, { <span class="comment">// MI operand encoding. // op1 -> modrm.rm // op2 -> imm - </span><span class="kw">let </span>(mode, rm) = <span class="kw">match </span>op1 { - MemOp::Indirect(..) => { + </span><span class="kw">let </span>(mode, rm) = <span class="kw">match </span>op1.mode() { + AddrMode::Indirect => { <span class="macro">assert!</span>(!op1.base().need_sib() && !op1.base().is_pc_rel()); (<span class="number">0b00</span>, op1.base().idx()) } - MemOp::IndirectDisp(..) => { + AddrMode::IndirectDisp => { <span class="macro">assert!</span>(!op1.base().need_sib()); (<span class="number">0b10</span>, op1.base().idx()) } - MemOp::IndirectBaseIndex(..) => { + AddrMode::IndirectBaseIndex => { <span class="macro">assert!</span>(!op1.base().is_pc_rel()); <span class="comment">// Using rsp as index register is interpreted as just base w/o offset. // https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing_2 @@ -692,37 +686,39 @@ </span>rm, <span class="comment">/* rm */ </span>); - <span class="kw">let </span>prefix = <<span class="self">Self </span><span class="kw">as </span>EncodeMI<T>>::legacy_prefix(); - <span class="kw">let </span>rex = <<span class="self">Self </span><span class="kw">as </span>EncodeMI<T>>::rex(<span class="kw-2">&</span>op1); + <span class="kw">let </span>prefix = <<span class="self">Self </span><span class="kw">as </span>EncodeMI<M>>::legacy_prefix(); + <span class="kw">let </span>rex = <<span class="self">Self </span><span class="kw">as </span>EncodeMI<M>>::rex(<span class="kw-2">&</span>op1); <span class="self">self</span>.emit_optional(<span class="kw-2">&</span>[prefix, rex]); <span class="self">self</span>.emit(<span class="kw-2">&</span>[opc, modrm]); - <span class="kw">match </span>op1 { - MemOp::Indirect(..) => {} - MemOp::IndirectDisp(<span class="kw">_</span>, disp) => <span class="self">self</span>.emit(<span class="kw-2">&</span>disp.to_ne_bytes()), - MemOp::IndirectBaseIndex(base, index) => <span class="self">self</span>.emit(<span class="kw-2">&</span>[sib(<span class="number">0</span>, index.idx(), base.idx())]), + <span class="kw">match </span>op1.mode() { + AddrMode::Indirect => {} + AddrMode::IndirectDisp => <span class="self">self</span>.emit(<span class="kw-2">&</span>op1.disp().to_ne_bytes()), + AddrMode::IndirectBaseIndex => { + <span class="self">self</span>.emit(<span class="kw-2">&</span>[sib(<span class="number">0</span>, op1.index().idx(), op1.base().idx())]) + } } <span class="self">self</span>.emit(op2.bytes()); } <span class="doccomment">/// Encode a memory-register instruction. - </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>encode_mr<T: Reg>(<span class="kw-2">&mut </span><span class="self">self</span>, opc: u8, op1: MemOp, op2: T) + </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>encode_mr<M: Mem, T: Reg>(<span class="kw-2">&mut </span><span class="self">self</span>, opc: u8, op1: M, op2: T) <span class="kw">where - </span><span class="self">Self</span>: EncodeMR<T>, + </span><span class="self">Self</span>: EncodeMR<M>, { <span class="comment">// MR operand encoding. // op1 -> modrm.rm // op2 -> modrm.reg - </span><span class="kw">let </span>(mode, rm) = <span class="kw">match </span>op1 { - MemOp::Indirect(..) => { + </span><span class="kw">let </span>(mode, rm) = <span class="kw">match </span>op1.mode() { + AddrMode::Indirect => { <span class="macro">assert!</span>(!op1.base().need_sib() && !op1.base().is_pc_rel()); (<span class="number">0b00</span>, op1.base().idx()) } - MemOp::IndirectDisp(..) => { + AddrMode::IndirectDisp => { <span class="macro">assert!</span>(!op1.base().need_sib()); (<span class="number">0b10</span>, op1.base().idx()) } - MemOp::IndirectBaseIndex(..) => { + AddrMode::IndirectBaseIndex => { <span class="macro">assert!</span>(!op1.base().is_pc_rel()); <span class="comment">// Using rsp as index register is interpreted as just base w/o offset. // https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing_2 @@ -738,22 +734,24 @@ </span>rm, <span class="comment">/* rm */ </span>); - <span class="kw">let </span>prefix = <<span class="self">Self </span><span class="kw">as </span>EncodeMR<T>>::legacy_prefix(); - <span class="kw">let </span>rex = <<span class="self">Self </span><span class="kw">as </span>EncodeMR<T>>::rex(<span class="kw-2">&</span>op1, op2); + <span class="kw">let </span>prefix = <<span class="self">Self </span><span class="kw">as </span>EncodeMR<M>>::legacy_prefix(); + <span class="kw">let </span>rex = <<span class="self">Self </span><span class="kw">as </span>EncodeMR<M>>::rex(<span class="kw-2">&</span>op1, op2); <span class="self">self</span>.emit_optional(<span class="kw-2">&</span>[prefix, rex]); <span class="self">self</span>.emit(<span class="kw-2">&</span>[opc, modrm]); - <span class="kw">match </span>op1 { - MemOp::Indirect(..) => {} - MemOp::IndirectDisp(<span class="kw">_</span>, disp) => <span class="self">self</span>.emit(<span class="kw-2">&</span>disp.to_ne_bytes()), - MemOp::IndirectBaseIndex(base, index) => <span class="self">self</span>.emit(<span class="kw-2">&</span>[sib(<span class="number">0</span>, index.idx(), base.idx())]), + <span class="kw">match </span>op1.mode() { + AddrMode::Indirect => {} + AddrMode::IndirectDisp => <span class="self">self</span>.emit(<span class="kw-2">&</span>op1.disp().to_ne_bytes()), + AddrMode::IndirectBaseIndex => { + <span class="self">self</span>.emit(<span class="kw-2">&</span>[sib(<span class="number">0</span>, op1.index().idx(), op1.base().idx())]) + } } } <span class="doccomment">/// Encode a register-memory instruction. - </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>encode_rm<T: Reg>(<span class="kw-2">&mut </span><span class="self">self</span>, opc: u8, op1: T, op2: MemOp) + </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>encode_rm<T: Reg, M: Mem>(<span class="kw-2">&mut </span><span class="self">self</span>, opc: u8, op1: T, op2: M) <span class="kw">where - </span><span class="self">Self</span>: EncodeMR<T>, + </span><span class="self">Self</span>: EncodeMR<M>, { <span class="comment">// RM operand encoding. // op1 -> modrm.reg @@ -829,15 +827,15 @@ <span class="kw">impl </span>EncodeR<Reg64> <span class="kw">for </span>Asm {} <span class="doccomment">/// Encode helper for memory-register instructions. -</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">trait </span>EncodeMR<T: Reg> { +</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">trait </span>EncodeMR<M: Mem> { <span class="kw">fn </span>legacy_prefix() -> <span class="prelude-ty">Option</span><u8> { <span class="prelude-val">None </span>} - <span class="kw">fn </span>rex(op1: <span class="kw-2">&</span>MemOp, op2: T) -> <span class="prelude-ty">Option</span><u8> { - <span class="kw">if </span>op2.need_rex() || op1.base().is_ext() || op1.index().is_ext() { + <span class="kw">fn </span>rex<T: Reg>(op1: <span class="kw-2">&</span>M, op2: T) -> <span class="prelude-ty">Option</span><u8> { + <span class="kw">if </span>M::is_64() || op2.is_ext() || op1.base().is_ext() || op1.index().is_ext() { <span class="prelude-val">Some</span>(rex( - op2.rexw(), + M::is_64(), op2.idx(), op1.index().idx(), op1.base().idx(), @@ -848,72 +846,60 @@ } } -<span class="kw">impl </span>EncodeMR<Reg8> <span class="kw">for </span>Asm {} -<span class="kw">impl </span>EncodeMR<Reg16> <span class="kw">for </span>Asm { +<span class="kw">impl </span>EncodeMR<Mem8> <span class="kw">for </span>Asm {} +<span class="kw">impl </span>EncodeMR<Mem16> <span class="kw">for </span>Asm { <span class="kw">fn </span>legacy_prefix() -> <span class="prelude-ty">Option</span><u8> { <span class="prelude-val">Some</span>(<span class="number">0x66</span>) } } -<span class="kw">impl </span>EncodeMR<Reg32> <span class="kw">for </span>Asm {} -<span class="kw">impl </span>EncodeMR<Reg64> <span class="kw">for </span>Asm {} +<span class="kw">impl </span>EncodeMR<Mem32> <span class="kw">for </span>Asm {} +<span class="kw">impl </span>EncodeMR<Mem64> <span class="kw">for </span>Asm {} <span class="doccomment">/// Encode helper for memory-immediate instructions. -</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">trait </span>EncodeMI<T: Imm> { +</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">trait </span>EncodeMI<M: Mem> { <span class="kw">fn </span>legacy_prefix() -> <span class="prelude-ty">Option</span><u8> { <span class="prelude-val">None </span>} - <span class="kw">fn </span>rex(op1: <span class="kw-2">&</span>MemOp) -> <span class="prelude-ty">Option</span><u8> { - <span class="kw">if </span>op1.base().is_ext() || op1.index().is_ext() { - <span class="prelude-val">Some</span>(rex(<span class="bool-val">false</span>, <span class="number">0</span>, op1.index().idx(), op1.base().idx())) + <span class="kw">fn </span>rex(op1: <span class="kw-2">&</span>M) -> <span class="prelude-ty">Option</span><u8> { + <span class="kw">if </span>M::is_64() || op1.base().is_ext() || op1.index().is_ext() { + <span class="prelude-val">Some</span>(rex(M::is_64(), <span class="number">0</span>, op1.index().idx(), op1.base().idx())) } <span class="kw">else </span>{ <span class="prelude-val">None </span>} } } -<span class="kw">impl </span>EncodeMI<Imm8> <span class="kw">for </span>Asm {} -<span class="kw">impl </span>EncodeMI<Imm16> <span class="kw">for </span>Asm { +<span class="kw">impl </span>EncodeMI<Mem8> <span class="kw">for </span>Asm {} +<span class="kw">impl </span>EncodeMI<Mem16> <span class="kw">for </span>Asm { <span class="kw">fn </span>legacy_prefix() -> <span class="prelude-ty">Option</span><u8> { <span class="prelude-val">Some</span>(<span class="number">0x66</span>) } } -<span class="kw">impl </span>EncodeMI<Imm32> <span class="kw">for </span>Asm {} +<span class="kw">impl </span>EncodeMI<Mem32> <span class="kw">for </span>Asm {} +<span class="kw">impl </span>EncodeMI<Mem64> <span class="kw">for </span>Asm {} <span class="doccomment">/// Encode helper for memory operand instructions. -</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">trait </span>EncodeM<T: MemOpSized> { +</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">trait </span>EncodeM<M: Mem> { <span class="kw">fn </span>legacy_prefix() -> <span class="prelude-ty">Option</span><u8> { <span class="prelude-val">None </span>} - <span class="kw">fn </span>rex(op1: <span class="kw-2">&</span>MemOp) -> <span class="prelude-ty">Option</span><u8> { - <span class="kw">if </span>op1.base().is_ext() || op1.index().is_ext() || <span class="self">Self</span>::is_64bit() { - <span class="prelude-val">Some</span>(rex( - <span class="self">Self</span>::is_64bit(), - <span class="number">0</span>, - op1.index().idx(), - op1.base().idx(), - )) + <span class="kw">fn </span>rex(op1: <span class="kw-2">&</span>M) -> <span class="prelude-ty">Option</span><u8> { + <span class="kw">if </span>M::is_64() || op1.base().is_ext() || op1.index().is_ext() { + <span class="prelude-val">Some</span>(rex(M::is_64(), <span class="number">0</span>, op1.index().idx(), op1.base().idx())) } <span class="kw">else </span>{ <span class="prelude-val">None </span>} } - - <span class="kw">fn </span>is_64bit() -> bool { - <span class="bool-val">false - </span>} } -<span class="kw">impl </span>EncodeM<MemOp8> <span class="kw">for </span>Asm {} -<span class="kw">impl </span>EncodeM<MemOp16> <span class="kw">for </span>Asm { +<span class="kw">impl </span>EncodeM<Mem8> <span class="kw">for </span>Asm {} +<span class="kw">impl </span>EncodeM<Mem16> <span class="kw">for </span>Asm { <span class="kw">fn </span>legacy_prefix() -> <span class="prelude-ty">Option</span><u8> { <span class="prelude-val">Some</span>(<span class="number">0x66</span>) } } -<span class="kw">impl </span>EncodeM<MemOp32> <span class="kw">for </span>Asm {} -<span class="kw">impl </span>EncodeM<MemOp64> <span class="kw">for </span>Asm { - <span class="kw">fn </span>is_64bit() -> bool { - <span class="bool-val">true - </span>} -} +<span class="kw">impl </span>EncodeM<Mem32> <span class="kw">for </span>Asm {} +<span class="kw">impl </span>EncodeM<Mem64> <span class="kw">for </span>Asm {} </code></pre></div></section></main></body></html>
\ No newline at end of file |