machinst x64: implement one way conditional jmp
This commit is contained in:
@@ -1021,6 +1021,18 @@ pub(crate) fn emit(
|
|||||||
sink.put4(nt_disp);
|
sink.put4(nt_disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inst::OneWayJmpCond { cc, dst } => {
|
||||||
|
let cond_start = sink.cur_offset();
|
||||||
|
let cond_disp_off = cond_start + 2;
|
||||||
|
if let Some(l) = dst.as_label() {
|
||||||
|
sink.use_label_at_offset(cond_disp_off, l, LabelUse::JmpRel32);
|
||||||
|
}
|
||||||
|
let dst_disp = dst.as_offset32_or_zero() as u32;
|
||||||
|
sink.put1(0x0F);
|
||||||
|
sink.put1(0x80 + cc.get_enc());
|
||||||
|
sink.put4(dst_disp);
|
||||||
|
}
|
||||||
|
|
||||||
Inst::JmpUnknown { target } => {
|
Inst::JmpUnknown { target } => {
|
||||||
match target {
|
match target {
|
||||||
RegMem::Reg { reg } => {
|
RegMem::Reg { reg } => {
|
||||||
|
|||||||
@@ -200,6 +200,10 @@ pub enum Inst {
|
|||||||
not_taken: BranchTarget,
|
not_taken: BranchTarget,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// A one-way conditional branch, invisible to the CFG processing; used *only* as part of
|
||||||
|
/// straight-line sequences in code to be emitted.
|
||||||
|
OneWayJmpCond { cc: CC, dst: BranchTarget },
|
||||||
|
|
||||||
/// Indirect jump: jmpq (reg mem).
|
/// Indirect jump: jmpq (reg mem).
|
||||||
JmpUnknown { target: RegMem },
|
JmpUnknown { target: RegMem },
|
||||||
|
|
||||||
@@ -634,7 +638,11 @@ impl ShowWithRRU for Inst {
|
|||||||
taken.show_rru(mb_rru),
|
taken.show_rru(mb_rru),
|
||||||
not_taken.show_rru(mb_rru)
|
not_taken.show_rru(mb_rru)
|
||||||
),
|
),
|
||||||
//
|
Inst::OneWayJmpCond { cc, dst } => format!(
|
||||||
|
"{} {}",
|
||||||
|
ljustify2("j".to_string(), cc.to_string()),
|
||||||
|
dst.show_rru(mb_rru),
|
||||||
|
),
|
||||||
Inst::JmpUnknown { target } => format!(
|
Inst::JmpUnknown { target } => format!(
|
||||||
"{} *{}",
|
"{} *{}",
|
||||||
ljustify("jmp".to_string()),
|
ljustify("jmp".to_string()),
|
||||||
@@ -757,6 +765,7 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
|
|||||||
| Inst::EpiloguePlaceholder
|
| Inst::EpiloguePlaceholder
|
||||||
| Inst::JmpKnown { .. }
|
| Inst::JmpKnown { .. }
|
||||||
| Inst::JmpCond { .. }
|
| Inst::JmpCond { .. }
|
||||||
|
| Inst::OneWayJmpCond { .. }
|
||||||
| Inst::Nop { .. }
|
| Inst::Nop { .. }
|
||||||
| Inst::JmpUnknown { .. }
|
| Inst::JmpUnknown { .. }
|
||||||
| Inst::VirtualSPOffsetAdj { .. }
|
| Inst::VirtualSPOffsetAdj { .. }
|
||||||
@@ -970,6 +979,7 @@ fn x64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
|
|||||||
| Inst::EpiloguePlaceholder
|
| Inst::EpiloguePlaceholder
|
||||||
| Inst::JmpKnown { .. }
|
| Inst::JmpKnown { .. }
|
||||||
| Inst::JmpCond { .. }
|
| Inst::JmpCond { .. }
|
||||||
|
| Inst::OneWayJmpCond { .. }
|
||||||
| Inst::Nop { .. }
|
| Inst::Nop { .. }
|
||||||
| Inst::JmpUnknown { .. }
|
| Inst::JmpUnknown { .. }
|
||||||
| Inst::VirtualSPOffsetAdj { .. }
|
| Inst::VirtualSPOffsetAdj { .. }
|
||||||
|
|||||||
Reference in New Issue
Block a user