Generate SSA code from returns (#5172)
Modify return pseudo-instructions to have pairs of registers: virtual and real. This allows us to constrain the virtual registers to the real ones specified by the abi, instead of directly emitting moves to those real registers.
This commit is contained in:
@@ -398,7 +398,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
Inst::Args { args }
|
||||
}
|
||||
|
||||
fn gen_ret(setup_frame: bool, isa_flags: &aarch64_settings::Flags, rets: Vec<Reg>) -> Inst {
|
||||
fn gen_ret(setup_frame: bool, isa_flags: &aarch64_settings::Flags, rets: Vec<RetPair>) -> Inst {
|
||||
if isa_flags.sign_return_address() && (setup_frame || isa_flags.sign_return_address_all()) {
|
||||
let key = if isa_flags.sign_return_address_with_bkey() {
|
||||
APIKey::B
|
||||
|
||||
@@ -787,7 +787,7 @@
|
||||
|
||||
;; A machine return instruction.
|
||||
(Ret
|
||||
(rets VecReg))
|
||||
(rets VecRetPair))
|
||||
|
||||
;; A machine return instruction with pointer authentication using SP as the
|
||||
;; modifier. This instruction requires pointer authentication support
|
||||
@@ -797,7 +797,7 @@
|
||||
(AuthenticatedRet
|
||||
(key APIKey)
|
||||
(is_hint bool)
|
||||
(rets VecReg))
|
||||
(rets VecRetPair))
|
||||
|
||||
;; An unconditional branch.
|
||||
(Jump
|
||||
|
||||
@@ -1022,8 +1022,8 @@ fn aarch64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
|
||||
}
|
||||
}
|
||||
&Inst::Ret { ref rets } | &Inst::AuthenticatedRet { ref rets, .. } => {
|
||||
for &ret in rets {
|
||||
collector.reg_use(ret);
|
||||
for ret in rets {
|
||||
collector.reg_fixed_use(ret.vreg, ret.preg);
|
||||
}
|
||||
}
|
||||
&Inst::Jump { .. } => {}
|
||||
|
||||
@@ -265,12 +265,15 @@ mod test {
|
||||
let buffer = backend.compile_function(&mut func, false).unwrap().buffer;
|
||||
let code = buffer.data();
|
||||
|
||||
// mov x3, #0x1234
|
||||
// add w0, w0, w3
|
||||
// ret
|
||||
let golden = vec![
|
||||
0x83, 0x46, 0x82, 0xd2, 0x00, 0x00, 0x03, 0x0b, 0xc0, 0x03, 0x5f, 0xd6,
|
||||
];
|
||||
// To update this comment, write the golden bytes to a file, and run the following command
|
||||
// on it to update:
|
||||
// > aarch64-linux-gnu-objdump -b binary -D <file> -m aarch64
|
||||
//
|
||||
// 0: d2824682 mov x2, #0x1234 // #4660
|
||||
// 4: 0b020000 add w0, w0, w2
|
||||
// 8: d65f03c0 ret
|
||||
|
||||
let golden = vec![130, 70, 130, 210, 0, 0, 2, 11, 192, 3, 95, 214];
|
||||
|
||||
assert_eq!(code, &golden[..]);
|
||||
}
|
||||
@@ -320,24 +323,28 @@ mod test {
|
||||
.unwrap();
|
||||
let code = result.buffer.data();
|
||||
|
||||
// mov x10, #0x1234 // #4660
|
||||
// add w12, w0, w10
|
||||
// mov w11, w12
|
||||
// cbnz x11, 0x20
|
||||
// mov x13, #0x1234 // #4660
|
||||
// add w15, w12, w13
|
||||
// mov w14, w15
|
||||
// cbnz x14, 0x10
|
||||
// mov w1, w12
|
||||
// cbnz x1, 0x10
|
||||
// mov x2, #0x1234 // #4660
|
||||
// sub w0, w12, w2
|
||||
// ret
|
||||
// To update this comment, write the golden bytes to a file, and run the following command
|
||||
// on it to update:
|
||||
// > aarch64-linux-gnu-objdump -b binary -D <file> -m aarch64
|
||||
//
|
||||
// 0: d2824689 mov x9, #0x1234 // #4660
|
||||
// 4: 0b09000b add w11, w0, w9
|
||||
// 8: 2a0b03ea mov w10, w11
|
||||
// c: b50000aa cbnz x10, 0x20
|
||||
// 10: d282468c mov x12, #0x1234 // #4660
|
||||
// 14: 0b0c016e add w14, w11, w12
|
||||
// 18: 2a0e03ed mov w13, w14
|
||||
// 1c: b5ffffad cbnz x13, 0x10
|
||||
// 20: 2a0b03e0 mov w0, w11
|
||||
// 24: b5ffff60 cbnz x0, 0x10
|
||||
// 28: d2824681 mov x1, #0x1234 // #4660
|
||||
// 2c: 4b010160 sub w0, w11, w1
|
||||
// 30: d65f03c0 ret
|
||||
|
||||
let golden = vec![
|
||||
138, 70, 130, 210, 12, 0, 10, 11, 235, 3, 12, 42, 171, 0, 0, 181, 141, 70, 130, 210,
|
||||
143, 1, 13, 11, 238, 3, 15, 42, 174, 255, 255, 181, 225, 3, 12, 42, 97, 255, 255, 181,
|
||||
130, 70, 130, 210, 128, 1, 2, 75, 192, 3, 95, 214,
|
||||
137, 70, 130, 210, 11, 0, 9, 11, 234, 3, 11, 42, 170, 0, 0, 181, 140, 70, 130, 210,
|
||||
110, 1, 12, 11, 237, 3, 14, 42, 173, 255, 255, 181, 224, 3, 11, 42, 96, 255, 255, 181,
|
||||
129, 70, 130, 210, 96, 1, 1, 75, 192, 3, 95, 214,
|
||||
];
|
||||
|
||||
assert_eq!(code, &golden[..]);
|
||||
@@ -393,14 +400,18 @@ mod test {
|
||||
.unwrap();
|
||||
let code = result.buffer.data();
|
||||
|
||||
// To update this comment, write the golden bytes to a file, and run the following command
|
||||
// on it to update:
|
||||
// > aarch64-linux-gnu-objdump -b binary -D <file> -m aarch64
|
||||
//
|
||||
// 0: 7100081f cmp w0, #0x2
|
||||
// 4: 54000122 b.cs 0x28 // b.hs, b.nlast
|
||||
// 8: 9a8023e9 csel x9, xzr, x0, cs // cs = hs, nlast
|
||||
// 8: 9a8023e8 csel x8, xzr, x0, cs // cs = hs, nlast
|
||||
// c: d503229f csdb
|
||||
// 10: 10000088 adr x8, 0x1c
|
||||
// 14: b8a95909 ldrsw x9, [x8, w9, uxtw #2]
|
||||
// 18: 8b090108 add x8, x8, x9
|
||||
// 1c: d61f0100 br x8
|
||||
// 10: 10000087 adr x7, 0x20
|
||||
// 14: b8a858e8 ldrsw x8, [x7, w8, uxtw #2]
|
||||
// 18: 8b0800e7 add x7, x7, x8
|
||||
// 1c: d61f00e0 br x7
|
||||
// 20: 00000010 udf #16
|
||||
// 24: 00000018 udf #24
|
||||
// 28: d2800060 mov x0, #0x3 // #3
|
||||
@@ -411,9 +422,10 @@ mod test {
|
||||
// 3c: d65f03c0 ret
|
||||
|
||||
let golden = vec![
|
||||
31, 8, 0, 113, 34, 1, 0, 84, 233, 35, 128, 154, 159, 34, 3, 213, 136, 0, 0, 16, 9, 89,
|
||||
169, 184, 8, 1, 9, 139, 0, 1, 31, 214, 16, 0, 0, 0, 24, 0, 0, 0, 96, 0, 128, 210, 192,
|
||||
3, 95, 214, 32, 0, 128, 210, 192, 3, 95, 214, 64, 0, 128, 210, 192, 3, 95, 214,
|
||||
31, 8, 0, 113, 34, 1, 0, 84, 232, 35, 128, 154, 159, 34, 3, 213, 135, 0, 0, 16, 232,
|
||||
88, 168, 184, 231, 0, 8, 139, 224, 0, 31, 214, 16, 0, 0, 0, 24, 0, 0, 0, 96, 0, 128,
|
||||
210, 192, 3, 95, 214, 32, 0, 128, 210, 192, 3, 95, 214, 64, 0, 128, 210, 192, 3, 95,
|
||||
214,
|
||||
];
|
||||
|
||||
assert_eq!(code, &golden[..]);
|
||||
|
||||
@@ -235,7 +235,7 @@ impl ABIMachineSpec for Riscv64MachineDeps {
|
||||
Inst::Args { args }
|
||||
}
|
||||
|
||||
fn gen_ret(_setup_frame: bool, _isa_flags: &Self::F, rets: Vec<Reg>) -> Inst {
|
||||
fn gen_ret(_setup_frame: bool, _isa_flags: &Self::F, rets: Vec<RetPair>) -> Inst {
|
||||
Inst::Ret { rets }
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
(Args
|
||||
(args VecArgPair))
|
||||
|
||||
(Ret (rets VecReg))
|
||||
(Ret (rets VecRetPair))
|
||||
|
||||
(Extend
|
||||
(rd WritableReg)
|
||||
|
||||
@@ -352,7 +352,9 @@ fn riscv64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
|
||||
}
|
||||
}
|
||||
&Inst::Ret { ref rets } => {
|
||||
collector.reg_uses(&rets[..]);
|
||||
for ret in rets {
|
||||
collector.reg_fixed_use(ret.vreg, ret.preg);
|
||||
}
|
||||
}
|
||||
|
||||
&Inst::Extend { rd, rn, .. } => {
|
||||
|
||||
@@ -233,13 +233,18 @@ mod test {
|
||||
);
|
||||
let buffer = backend.compile_function(&mut func, true).unwrap();
|
||||
let code = buffer.buffer.data();
|
||||
// 0: 000015b7 lui a1,0x1
|
||||
// 4: 23458593 addi a1,a1,564 # 0x1234
|
||||
// 8: 00b5053b addw a0,a0,a1
|
||||
|
||||
// To update this comment, write the golden bytes to a file, and run the following command
|
||||
// on it to update:
|
||||
// > riscv64-linux-gnu-objdump -b binary -D <file> -m riscv
|
||||
//
|
||||
// 0: 000013b7 lui t2,0x1
|
||||
// 4: 23438393 addi t2,t2,564 # 0x1234
|
||||
// 8: 0075053b .4byte 0x75053b
|
||||
// c: 00008067 ret
|
||||
|
||||
let golden = vec![
|
||||
0xb7, 0x15, 0x0, 0x0, 0x93, 0x85, 0x45, 0x23, 0x3b, 0x5, 0xb5, 0x0, 0x67, 0x80, 0x0,
|
||||
0x0,
|
||||
183, 19, 0, 0, 147, 131, 67, 35, 59, 5, 117, 0, 103, 128, 0, 0,
|
||||
];
|
||||
assert_eq!(code, &golden[..]);
|
||||
}
|
||||
|
||||
@@ -457,7 +457,7 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
Inst::Args { args }
|
||||
}
|
||||
|
||||
fn gen_ret(_setup_frame: bool, _isa_flags: &s390x_settings::Flags, rets: Vec<Reg>) -> Inst {
|
||||
fn gen_ret(_setup_frame: bool, _isa_flags: &s390x_settings::Flags, rets: Vec<RetPair>) -> Inst {
|
||||
Inst::Ret {
|
||||
link: gpr(14),
|
||||
rets,
|
||||
|
||||
@@ -906,7 +906,7 @@
|
||||
;; A machine return instruction.
|
||||
(Ret
|
||||
(link Reg)
|
||||
(rets VecReg))
|
||||
(rets VecRetPair))
|
||||
|
||||
;; An unconditional branch.
|
||||
(Jump
|
||||
|
||||
@@ -3480,7 +3480,7 @@ impl Inst {
|
||||
}
|
||||
|
||||
&Inst::Call { link, ref info } => {
|
||||
let link = allocs.next_writable(link);
|
||||
debug_assert_eq!(link.to_reg(), gpr(14));
|
||||
|
||||
// Add relocation for TLS libcalls to enable linker optimizations.
|
||||
match &info.tls_symbol {
|
||||
@@ -3509,7 +3509,7 @@ impl Inst {
|
||||
}
|
||||
}
|
||||
&Inst::CallInd { link, ref info } => {
|
||||
let link = allocs.next_writable(link);
|
||||
debug_assert_eq!(link.to_reg(), gpr(14));
|
||||
let rn = allocs.next(info.rn);
|
||||
|
||||
let opcode = 0x0d; // BASR
|
||||
@@ -3523,7 +3523,7 @@ impl Inst {
|
||||
}
|
||||
&Inst::Args { .. } => {}
|
||||
&Inst::Ret { link, .. } => {
|
||||
let link = allocs.next(link);
|
||||
debug_assert_eq!(link, gpr(14));
|
||||
|
||||
let opcode = 0x07; // BCR
|
||||
put(sink, &enc_rr(opcode, gpr(15), link));
|
||||
|
||||
@@ -1009,17 +1009,17 @@ fn s390x_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandC
|
||||
collector.reg_use(rn);
|
||||
}
|
||||
&Inst::Call { link, ref info } => {
|
||||
collector.reg_def(link);
|
||||
for u in &info.uses {
|
||||
collector.reg_fixed_use(u.vreg, u.preg);
|
||||
}
|
||||
for d in &info.defs {
|
||||
collector.reg_fixed_def(d.vreg, d.preg);
|
||||
}
|
||||
collector.reg_clobbers(info.clobbers);
|
||||
let mut clobbers = info.clobbers.clone();
|
||||
clobbers.add(link.to_reg().to_real_reg().unwrap().into());
|
||||
collector.reg_clobbers(clobbers);
|
||||
}
|
||||
&Inst::CallInd { link, ref info } => {
|
||||
collector.reg_def(link);
|
||||
collector.reg_use(info.rn);
|
||||
for u in &info.uses {
|
||||
collector.reg_fixed_use(u.vreg, u.preg);
|
||||
@@ -1027,16 +1027,21 @@ fn s390x_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandC
|
||||
for d in &info.defs {
|
||||
collector.reg_fixed_def(d.vreg, d.preg);
|
||||
}
|
||||
collector.reg_clobbers(info.clobbers);
|
||||
let mut clobbers = info.clobbers.clone();
|
||||
clobbers.add(link.to_reg().to_real_reg().unwrap().into());
|
||||
collector.reg_clobbers(clobbers);
|
||||
}
|
||||
&Inst::Args { ref args } => {
|
||||
for arg in args {
|
||||
collector.reg_fixed_def(arg.vreg, arg.preg);
|
||||
}
|
||||
}
|
||||
&Inst::Ret { link, ref rets } => {
|
||||
collector.reg_use(link);
|
||||
collector.reg_uses(&rets[..]);
|
||||
&Inst::Ret { ref rets, .. } => {
|
||||
// NOTE: we explicitly don't mark the link register as used here, as the use is only in
|
||||
// the epilog where callee-save registers are restored.
|
||||
for ret in rets {
|
||||
collector.reg_fixed_use(ret.vreg, ret.preg);
|
||||
}
|
||||
}
|
||||
&Inst::Jump { .. } => {}
|
||||
&Inst::IndirectBr { rn, .. } => {
|
||||
@@ -3231,7 +3236,7 @@ impl Inst {
|
||||
format!("{} {}, {}", op, rd, rn)
|
||||
}
|
||||
&Inst::Call { link, ref info, .. } => {
|
||||
let link = pretty_print_reg(link.to_reg(), allocs);
|
||||
let link = link.to_reg();
|
||||
let tls_symbol = match &info.tls_symbol {
|
||||
None => "".to_string(),
|
||||
Some(SymbolReloc::TlsGd { name }) => {
|
||||
@@ -3239,12 +3244,19 @@ impl Inst {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
format!("brasl {}, {}{}", link, info.dest.display(None), tls_symbol)
|
||||
debug_assert_eq!(link, gpr(14));
|
||||
format!(
|
||||
"brasl {}, {}{}",
|
||||
show_reg(link),
|
||||
info.dest.display(None),
|
||||
tls_symbol
|
||||
)
|
||||
}
|
||||
&Inst::CallInd { link, ref info, .. } => {
|
||||
let link = pretty_print_reg(link.to_reg(), allocs);
|
||||
let link = link.to_reg();
|
||||
let rn = pretty_print_reg(info.rn, allocs);
|
||||
format!("basr {}, {}", link, rn)
|
||||
debug_assert_eq!(link, gpr(14));
|
||||
format!("basr {}, {}", show_reg(link), rn)
|
||||
}
|
||||
&Inst::Args { ref args } => {
|
||||
let mut s = "args".to_string();
|
||||
@@ -3257,8 +3269,8 @@ impl Inst {
|
||||
s
|
||||
}
|
||||
&Inst::Ret { link, .. } => {
|
||||
let link = pretty_print_reg(link, allocs);
|
||||
format!("br {}", link)
|
||||
debug_assert_eq!(link, gpr(14));
|
||||
format!("br {}", show_reg(link))
|
||||
}
|
||||
&Inst::Jump { dest } => {
|
||||
let dest = dest.to_string();
|
||||
|
||||
@@ -298,26 +298,25 @@ mod test {
|
||||
|
||||
// FIXME: the branching logic should be optimized more
|
||||
|
||||
// ahi %r2, 4660
|
||||
// chi %r2, 0
|
||||
// jglh label1 ; jg label2
|
||||
// jg label6
|
||||
// jg label3
|
||||
// ahik %r3, %r2, 4660
|
||||
// chi %r3, 0
|
||||
// jglh label4 ; jg label5
|
||||
// jg label3
|
||||
// jg label6
|
||||
// chi %r2, 0
|
||||
// jglh label7 ; jg label8
|
||||
// jg label3
|
||||
// ahi %r2, -4660
|
||||
// br %r14
|
||||
// To update this comment, write the golden bytes to a file, and run the following command
|
||||
// on it to update:
|
||||
// > s390x-linux-gnu-objdump -b binary -D <file> -m s390
|
||||
//
|
||||
// 0: a7 2a 12 34 ahi %r2,4660
|
||||
// 4: a7 2e 00 00 chi %r2,0
|
||||
// 8: c0 64 00 00 00 0b jglh 0x1e
|
||||
// e: ec 32 12 34 00 d8 ahik %r3,%r2,4660
|
||||
// 14: a7 3e 00 00 chi %r3,0
|
||||
// 18: c0 64 ff ff ff fb jglh 0xe
|
||||
// 1e: a7 2e 00 00 chi %r2,0
|
||||
// 22: c0 64 ff ff ff f6 jglh 0xe
|
||||
// 28: a7 2a ed cc ahi %r2,-4660
|
||||
// 2c: 07 fe br %r14
|
||||
|
||||
let golden = vec![
|
||||
236, 50, 18, 52, 0, 216, 167, 62, 0, 0, 192, 100, 0, 0, 0, 11, 236, 67, 18, 52, 0, 216,
|
||||
167, 78, 0, 0, 192, 100, 255, 255, 255, 251, 167, 62, 0, 0, 192, 100, 255, 255, 255,
|
||||
246, 236, 35, 237, 204, 0, 216, 7, 254,
|
||||
167, 42, 18, 52, 167, 46, 0, 0, 192, 100, 0, 0, 0, 11, 236, 50, 18, 52, 0, 216, 167,
|
||||
62, 0, 0, 192, 100, 255, 255, 255, 251, 167, 46, 0, 0, 192, 100, 255, 255, 255, 246,
|
||||
167, 42, 237, 204, 7, 254,
|
||||
];
|
||||
|
||||
assert_eq!(code, &golden[..]);
|
||||
|
||||
@@ -298,7 +298,11 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
Inst::Args { args }
|
||||
}
|
||||
|
||||
fn gen_ret(_setup_frame: bool, _isa_flags: &x64_settings::Flags, rets: Vec<Reg>) -> Self::I {
|
||||
fn gen_ret(
|
||||
_setup_frame: bool,
|
||||
_isa_flags: &x64_settings::Flags,
|
||||
rets: Vec<RetPair>,
|
||||
) -> Self::I {
|
||||
Inst::ret(rets)
|
||||
}
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@
|
||||
(args VecArgPair))
|
||||
|
||||
;; Return.
|
||||
(Ret (rets VecReg))
|
||||
(Ret (rets VecRetPair))
|
||||
|
||||
;; Jump to a known target: jmp simm32.
|
||||
(JmpKnown (dst MachLabel))
|
||||
|
||||
@@ -526,7 +526,7 @@ impl Inst {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn ret(rets: Vec<Reg>) -> Inst {
|
||||
pub(crate) fn ret(rets: Vec<RetPair>) -> Inst {
|
||||
Inst::Ret { rets }
|
||||
}
|
||||
|
||||
@@ -2081,8 +2081,8 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
|
||||
Inst::Ret { rets } => {
|
||||
// The return value(s) are live-out; we represent this
|
||||
// with register uses on the return instruction.
|
||||
for &ret in rets {
|
||||
collector.reg_use(ret);
|
||||
for ret in rets.iter() {
|
||||
collector.reg_fixed_use(ret.vreg, ret.preg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -333,31 +333,36 @@ mod test {
|
||||
.unwrap();
|
||||
let code = result.buffer.data();
|
||||
|
||||
// 00000000 55 push rbp
|
||||
// 00000001 4889E5 mov rbp,rsp
|
||||
// 00000004 81C734120000 add edi,0x1234
|
||||
// 0000000A 85FF test edi,edi
|
||||
// 0000000C 0F841C000000 jz near 0x2e
|
||||
// 00000012 4989F8 mov r8,rdi
|
||||
// 00000015 4889F8 mov rax,rdi
|
||||
// 00000018 81E834120000 sub eax,0x1234
|
||||
// 0000001E 4401C0 add eax,r8d
|
||||
// 00000021 85FF test edi,edi
|
||||
// 00000023 0F8505000000 jnz near 0x2e
|
||||
// 00000029 4889EC mov rsp,rbp
|
||||
// 0000002C 5D pop rbp
|
||||
// 0000002D C3 ret
|
||||
// 0000002E 4989F8 mov r8,rdi
|
||||
// 00000031 4181C034120000 add r8d,0x1234
|
||||
// 00000038 4585C0 test r8d,r8d
|
||||
// 0000003B 0F85EDFFFFFF jnz near 0x2e
|
||||
// 00000041 E9CFFFFFFF jmp 0x15
|
||||
// To update this comment, write the golden bytes to a file, and run the following
|
||||
// command on it:
|
||||
// > objdump -b binary -D <file> -m i386:x86-64 -M intel
|
||||
//
|
||||
// 0: 55 push rbp
|
||||
// 1: 48 89 e5 mov rbp,rsp
|
||||
// 4: 48 89 fe mov rsi,rdi
|
||||
// 7: 81 c6 34 12 00 00 add esi,0x1234
|
||||
// d: 85 f6 test esi,esi
|
||||
// f: 0f 84 1c 00 00 00 je 0x31
|
||||
// 15: 49 89 f0 mov r8,rsi
|
||||
// 18: 48 89 f0 mov rax,rsi
|
||||
// 1b: 81 e8 34 12 00 00 sub eax,0x1234
|
||||
// 21: 44 01 c0 add eax,r8d
|
||||
// 24: 85 f6 test esi,esi
|
||||
// 26: 0f 85 05 00 00 00 jne 0x31
|
||||
// 2c: 48 89 ec mov rsp,rbp
|
||||
// 2f: 5d pop rbp
|
||||
// 30: c3 ret
|
||||
// 31: 49 89 f0 mov r8,rsi
|
||||
// 34: 41 81 c0 34 12 00 00 add r8d,0x1234
|
||||
// 3b: 45 85 c0 test r8d,r8d
|
||||
// 3e: 0f 85 ed ff ff ff jne 0x31
|
||||
// 44: e9 cf ff ff ff jmp 0x18
|
||||
|
||||
let golden = vec![
|
||||
85, 72, 137, 229, 129, 199, 52, 18, 0, 0, 133, 255, 15, 132, 28, 0, 0, 0, 73, 137, 248,
|
||||
72, 137, 248, 129, 232, 52, 18, 0, 0, 68, 1, 192, 133, 255, 15, 133, 5, 0, 0, 0, 72,
|
||||
137, 236, 93, 195, 73, 137, 248, 65, 129, 192, 52, 18, 0, 0, 69, 133, 192, 15, 133,
|
||||
237, 255, 255, 255, 233, 207, 255, 255, 255,
|
||||
85, 72, 137, 229, 72, 137, 254, 129, 198, 52, 18, 0, 0, 133, 246, 15, 132, 28, 0, 0, 0,
|
||||
73, 137, 240, 72, 137, 240, 129, 232, 52, 18, 0, 0, 68, 1, 192, 133, 246, 15, 133, 5,
|
||||
0, 0, 0, 72, 137, 236, 93, 195, 73, 137, 240, 65, 129, 192, 52, 18, 0, 0, 69, 133, 192,
|
||||
15, 133, 237, 255, 255, 255, 233, 207, 255, 255, 255,
|
||||
];
|
||||
|
||||
assert_eq!(code, &golden[..]);
|
||||
@@ -433,35 +438,42 @@ mod test {
|
||||
.unwrap();
|
||||
let code = result.buffer.data();
|
||||
|
||||
// 00000000 55 push rbp
|
||||
// 00000001 4889E5 mov rbp,rsp
|
||||
// 00000004 83FF02 cmp edi,byte +0x2
|
||||
// 00000007 0F8327000000 jnc near 0x34
|
||||
// 0000000D 448BDF mov r11d,edi
|
||||
// 00000010 41BA00000000 mov r10d,0x0
|
||||
// 00000016 4D0F43DA cmovnc r11,r10
|
||||
// 0000001A 4C8D150B000000 lea r10,[rel 0x2c]
|
||||
// 00000021 4F635C9A00 movsxd r11,dword [r10+r11*4+0x0]
|
||||
// 00000026 4D01DA add r10,r11
|
||||
// 00000029 41FFE2 jmp r10
|
||||
// 0000002C 120000001C000000 (jumptable data)
|
||||
// 00000034 B803000000 mov eax,0x3
|
||||
// 00000039 4889EC mov rsp,rbp
|
||||
// 0000003C 5D pop rbp
|
||||
// 0000003D C3 ret
|
||||
// 0000003E B801000000 mov eax,0x1
|
||||
// 00000043 4889EC mov rsp,rbp
|
||||
// 00000046 5D pop rbp
|
||||
// 00000047 C3 ret
|
||||
// 00000048 B802000000 mov eax,0x2
|
||||
// 0000004D 4889EC mov rsp,rbp
|
||||
// 00000050 5D pop rbp
|
||||
// 00000051 C3 ret
|
||||
// To update this comment, write the golden bytes to a file, and run the following
|
||||
// command on it:
|
||||
// > objdump -b binary -D <file> -m i386:x86-64 -M intel
|
||||
//
|
||||
// 0: 55 push rbp
|
||||
// 1: 48 89 e5 mov rbp,rsp
|
||||
// 4: 83 ff 02 cmp edi,0x2
|
||||
// 7: 0f 83 27 00 00 00 jae 0x34
|
||||
// d: 44 8b d7 mov r10d,edi
|
||||
// 10: 41 b9 00 00 00 00 mov r9d,0x0
|
||||
// 16: 4d 0f 43 d1 cmovae r10,r9
|
||||
// 1a: 4c 8d 0d 0b 00 00 00 lea r9,[rip+0xb] # 0x2c
|
||||
// 21: 4f 63 54 91 00 movsxd r10,DWORD PTR [r9+r10*4+0x0]
|
||||
// 26: 4d 01 d1 add r9,r10
|
||||
// 29: 41 ff e1 jmp r9
|
||||
// 2c: 12 00 adc al,BYTE PTR [rax]
|
||||
// 2e: 00 00 add BYTE PTR [rax],al
|
||||
// 30: 1c 00 sbb al,0x0
|
||||
// 32: 00 00 add BYTE PTR [rax],al
|
||||
// 34: b8 03 00 00 00 mov eax,0x3
|
||||
// 39: 48 89 ec mov rsp,rbp
|
||||
// 3c: 5d pop rbp
|
||||
// 3d: c3 ret
|
||||
// 3e: b8 01 00 00 00 mov eax,0x1
|
||||
// 43: 48 89 ec mov rsp,rbp
|
||||
// 46: 5d pop rbp
|
||||
// 47: c3 ret
|
||||
// 48: b8 02 00 00 00 mov eax,0x2
|
||||
// 4d: 48 89 ec mov rsp,rbp
|
||||
// 50: 5d pop rbp
|
||||
// 51: c3 ret
|
||||
|
||||
let golden = vec![
|
||||
85, 72, 137, 229, 131, 255, 2, 15, 131, 39, 0, 0, 0, 68, 139, 223, 65, 186, 0, 0, 0, 0,
|
||||
77, 15, 67, 218, 76, 141, 21, 11, 0, 0, 0, 79, 99, 92, 154, 0, 77, 1, 218, 65, 255,
|
||||
226, 18, 0, 0, 0, 28, 0, 0, 0, 184, 3, 0, 0, 0, 72, 137, 236, 93, 195, 184, 1, 0, 0, 0,
|
||||
85, 72, 137, 229, 131, 255, 2, 15, 131, 39, 0, 0, 0, 68, 139, 215, 65, 185, 0, 0, 0, 0,
|
||||
77, 15, 67, 209, 76, 141, 13, 11, 0, 0, 0, 79, 99, 84, 145, 0, 77, 1, 209, 65, 255,
|
||||
225, 18, 0, 0, 0, 28, 0, 0, 0, 184, 3, 0, 0, 0, 72, 137, 236, 93, 195, 184, 1, 0, 0, 0,
|
||||
72, 137, 236, 93, 195, 184, 2, 0, 0, 0, 72, 137, 236, 93, 195,
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user