Compile a simple function (#2)

* Implement basics.

* Execute code

* Add wasm2wat test cases.

* abi_loc_for_arg for stack.

* Assert that sp_depth is 0 at the epilogue

* Do 32bit add.

* Assert that RAX can be used as a scratch register

* Reuse assembler.

* Align stack slots.
This commit is contained in:
Sergey Pepyakin
2018-11-08 22:56:27 +01:00
committed by Dan Gohman
parent d3bc26bc93
commit 08240761d5
9 changed files with 338 additions and 72 deletions

View File

@@ -1,34 +1,48 @@
use backend::*;
use disassemble::disassemble;
use error::Error;
use wasmparser::{FunctionBody, Operator};
pub fn translate(body: &FunctionBody) -> Result<(), Error> {
pub fn translate(session: &mut CodeGenSession, body: &FunctionBody) -> Result<(), Error> {
let locals = body.get_locals_reader()?;
// Assume signature is (i32, i32) -> i32 for now.
// TODO: Use a real signature
const ARG_COUNT: u32 = 2;
let mut framesize = ARG_COUNT;
for local in locals {
local?; // TODO
let (count, _ty) = local?;
framesize += count;
}
let mut ops = dynasmrt::x64::Assembler::new().unwrap();
let mut ctx = session.new_context();
let operators = body.get_operators_reader()?;
let mut regs = Registers::new();
prologue(&mut ctx, framesize);
for arg_pos in 0..ARG_COUNT {
copy_incoming_arg(&mut ctx, arg_pos);
}
for op in operators {
match op? {
Operator::I32Add => {
add_i32(&mut ops, &mut regs);
add_i32(&mut ctx);
}
Operator::GetLocal { local_index } => {
get_local_i32(&mut ctx, local_index);
}
Operator::End => {
// TODO: This is super naive and makes a lot of unfounded assumptions
// but will do for the start.
prepare_return_value(&mut ctx);
}
_ => {
unsupported_opcode(&mut ops);
unsupported_opcode(&mut ctx);
}
}
}
let output = ops
.finalize()
.map_err(|_asm| Error::Assembler("assembler error".to_owned()))?;
// TODO: Do something with the output.
disassemble(&output)?;
epilogue(&mut ctx);
Ok(())
}