use std::{error::Error, fs::OpenOptions, path::Path};
use ygen::debug::{DebugLocation, DebugRegistry};
use ygen::{Obj::*, Target::Triple};
use ygen::Target::x64::{instr::*, x64Reg};
fn main() -> Result<(), Box<dyn Error>> {
let mut obj = ObjectBuilder::new(
Triple::parse("x86_64-pc-windows")?
);
obj.decls(vec![
("main", Decl::Function, Linkage::External),
("string", Decl::Constant, Linkage::Internal),
("printf", Decl::Function, Linkage::Extern),
]);
let mut debug = DebugRegistry::new("ygen example".to_string(), gimli::DW_LANG_C, Path::new("test.c"));
let mut data = vec![];
data.extend_from_slice(&X64MCInstr::with1(Mnemonic::Push, Operand::Reg(x64Reg::Rbp)).compile()?);
data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Sub, Operand::Reg(x64Reg::Rsp), Operand::Imm(40)).compile()?);
debug.add_location(&"main".to_string(), DebugLocation { line: 3, col: 0, epilog: false, prolog: true, adr: data.len() as u64 });
let rip_relativ = Operand::Mem(MemOp { base: None, index: None, scale: 1, displ: 0, rip: true });
data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Lea, Operand::Reg(x64Reg::Rax), rip_relativ).compile()?);
obj.link( Link { from: "main".into(), to: "string".into(), at: data.len(), addend: -4, special: false });
if cfg!(target_os = "windows") {
data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(x64Reg::Rcx), Operand::Reg(x64Reg::Rax)).compile()?);
} else {
data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(x64Reg::Rsi), Operand::Reg(x64Reg::Rax)).compile()?);
}
debug.add_location(&"main".to_string(), DebugLocation { line: 4, col: 4, epilog: false, prolog: false, adr: data.len() as u64 });
data.extend_from_slice(&X64MCInstr::with1(Mnemonic::Call, Operand::Imm(0)).compile()?);
obj.link( Link { from: "main".into(), to: "printf".into(), at: data.len(), addend: -4, special: false });
debug.add_location(&"main".to_string(), DebugLocation { line: 5, col: 4, epilog: false, prolog: false, adr: data.len() as u64 });
data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Xor, Operand::Reg(x64Reg::Eax), Operand::Reg(x64Reg::Eax)).compile()?);
debug.add_location(&"main".to_string(), DebugLocation { line: 6, col: 0, epilog: true, prolog: false, adr: data.len() as u64 });
data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Add, Operand::Reg(x64Reg::Rsp), Operand::Imm(40)).compile()?);
data.extend_from_slice(&X64MCInstr::with0(Mnemonic::Ret).compile()?);
obj.define("main", data);
obj.define("string", b"Hello World!\n\0".into());
obj.debug = true;
obj.emit(
OpenOptions::new().create(true).write(true).open("output.o")?, Some(debug)
)?;
Ok(())
}