idea (doesn't compile)
This commit is contained in:
+42
-32
@@ -72,23 +72,7 @@ fn compile_instr(encoder: &mut Encoder, instr: &BInstr) -> Result<(), CompilerMs
|
||||
impl Encoder<'_> {
|
||||
// assembly
|
||||
|
||||
pub fn movi(&mut self, dst: RegWH, imm: u64) -> Result<(), CompilerMsg> {
|
||||
if dst.widthh == WidthH::B16 {
|
||||
self.data.push(0x66);
|
||||
}
|
||||
if dst.requires_rex() {
|
||||
self.data.push(rex(dst.widthh, 0, 0, dst));
|
||||
}
|
||||
if imm > dst.widthh.max() {
|
||||
return Err("immediate cannot fit in register".into());
|
||||
}
|
||||
let opcode = 0xb0 | ((dst.widthh.gt8() as u8) << 3);
|
||||
self.data.push(opcode | dst.base());
|
||||
self.data.extend(&imm.to_le_bytes()[..dst.widthh.bytes()]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn movr(&mut self, dst: RegH, src: RegH, width: Width) {
|
||||
pub fn mov_rr(&mut self, dst: RegH, src: RegH, width: Width) {
|
||||
if width == Width::B16 {
|
||||
self.data.push(0x66);
|
||||
}
|
||||
@@ -99,10 +83,30 @@ impl Encoder<'_> {
|
||||
self.data.push(modrm_regs(src, dst));
|
||||
}
|
||||
|
||||
pub fn movm(&mut self, reg: RegWH, offset: u32, val: u32) {
|
||||
self.data.extend([rex(1, reg, 0, 0), 0xc7]);
|
||||
self.modrm_regdisp(reg, offset);
|
||||
self.data.extend(val.to_le_bytes());
|
||||
pub fn mov_ri(&mut self, dst: RegWH, src: u64) -> Result<(), CompilerMsg> {
|
||||
if dst.width == Width::B16 {
|
||||
self.data.push(0x66);
|
||||
}
|
||||
if dst.requires_rex() {
|
||||
self.data.push(rex(dst.width, 0, 0, dst));
|
||||
}
|
||||
if src > dst.width.max() {
|
||||
return Err("immediate cannot fit in register".into());
|
||||
}
|
||||
let opcode = 0xb0 | ((dst.width.gt8() as u8) << 3);
|
||||
self.data.push(opcode | dst.base());
|
||||
self.data.extend(&src.to_le_bytes()[..dst.width.bytes()]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn mov_rm(&mut self, dst: RegWH, src: Mem) {}
|
||||
|
||||
pub fn mov_mr(&mut self, dst: Mem, src: RegWH) {}
|
||||
|
||||
pub fn mov_mi(&mut self, dst: Mem, src: u32) {
|
||||
self.data.extend([rex(1, dst.reg, 0, 0), 0xc7]);
|
||||
self.modrm_regdisp(dst.reg, dst.disp);
|
||||
self.data.extend(src.to_le_bytes());
|
||||
}
|
||||
|
||||
pub fn lea(&mut self, dst: RegWH, sym: Symbol) {
|
||||
@@ -119,12 +123,12 @@ impl Encoder<'_> {
|
||||
self.data.extend([0x0f, 0x05])
|
||||
}
|
||||
|
||||
pub fn call(&mut self, sym: Symbol) {
|
||||
pub fn call_i(&mut self, sym: Symbol) {
|
||||
self.data.push(0xe8);
|
||||
self.sym_offset4(sym);
|
||||
}
|
||||
|
||||
pub fn callm(&mut self, sym: Symbol) {
|
||||
pub fn call_m(&mut self, sym: Symbol) {
|
||||
self.data.extend([0xff, 0x15]);
|
||||
self.sym_offset4(sym);
|
||||
}
|
||||
@@ -133,14 +137,14 @@ impl Encoder<'_> {
|
||||
self.data.push(0xc3);
|
||||
}
|
||||
|
||||
pub fn pushr(&mut self, reg: Reg) {
|
||||
pub fn push_r(&mut self, reg: Reg, width: Width64) {
|
||||
if reg.gt8() {
|
||||
self.data.push(0x41);
|
||||
}
|
||||
self.data.push(0x50 | reg.base());
|
||||
}
|
||||
|
||||
pub fn pushi(&mut self, imm: u32) {
|
||||
pub fn push_i(&mut self, imm: u32) {
|
||||
const U8: u32 = 2 << 8;
|
||||
if let 0..U8 = imm {
|
||||
self.data.push(0x6a);
|
||||
@@ -175,17 +179,23 @@ impl Encoder<'_> {
|
||||
|
||||
pub fn asm(&mut self, instr: Instr) -> Result<(), CompilerMsg> {
|
||||
match instr {
|
||||
Instr::Movr { dst, src, width } => self.movr(dst, src, width),
|
||||
Instr::Movi { dst, imm } => self.movi(dst, imm)?,
|
||||
Instr::Movm { reg, offset, val } => self.movm(reg, offset, val),
|
||||
Instr::Mov(v) => match v {
|
||||
Mov::RR { dst, src, width } => self.mov_rr(dst, src, width),
|
||||
Mov::RI { dst, src } => self.mov_ri(dst, src)?,
|
||||
Mov::RM { dst, src } => self.mov_rm(dst, src),
|
||||
Mov::MI { dst, src } => self.mov_mi(dst, src),
|
||||
Mov::MR { dst, src } => self.mov_mr(dst, src),
|
||||
},
|
||||
Instr::Int(code) => self.int(code),
|
||||
Instr::Syscall => self.syscall(),
|
||||
Instr::Lea { dst, sym } => self.lea(dst, sym),
|
||||
Instr::Call(sym) => self.call(sym),
|
||||
Instr::Callm(sym) => self.callm(sym),
|
||||
Instr::Call(sym) => self.call_i(sym),
|
||||
Instr::CallM(sym) => self.call_m(sym),
|
||||
Instr::Ret => self.ret(),
|
||||
Instr::Pushr(reg) => self.pushr(reg),
|
||||
Instr::Pushi(imm) => self.pushi(imm),
|
||||
Instr::Push(v) => match v {
|
||||
Push::Reg(reg, width) => self.push_r(reg, width),
|
||||
Push::Imm(imm) => self.push_i(imm),
|
||||
},
|
||||
Instr::Pop(reg) => self.pop(reg),
|
||||
Instr::Sub => self.data.extend([0x48, 0x83, 0xec, 0x28]),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user