From ae76cfb9cd2915318fb14a3aedfb2753789f5e68 Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Wed, 25 Mar 2015 12:23:51 -0400 Subject: start writing some codegen --- lo2.ml | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/lo2.ml b/lo2.ml index 761e642..6331185 100644 --- a/lo2.ml +++ b/lo2.ml @@ -363,6 +363,68 @@ let movgen (p: rprog): mprog = } ) +let codegen (p: mprog): string = + let cl = ref [] in + let outs s = cl := s :: !cl in + let outb b = outs (String.make 1 (Char.chr b)) in + + let regmap = [| (* only caller-save regs, for now *) + 0; (* rax *) + 1; (* rcx *) + 2; (* rdx *) + 6; (* rsi *) + 7; (* rdi *) + 8; (* r8 *) + 9; (* r9 *) + 10; (* r10 *) + 11; (* r11 *) + |] in + let regn = function + | LReg r -> regmap.(r+1) + | _ -> failwith "register expected in regn" in + + let rexp rg rm = + let rex = 0x48 in + let rg, rex = if rg > 7 + then rg-8, rex lor 4 + else rg, rex in + let rm, rex = if rm > 7 + then rm-8, rex lor 1 + else rm, rex in + (rex, rg, rm) in + + let modrm ?(md=3) r m = + (md lsl 6) + (r lsl 3) + m in + + let arit op r r1 r2 = + if r <> r1 && op <> 0xf7 then begin (* HACK *) + let rex, r1, r = rexp r1 r in + outb rex; outb 0x89; outb (modrm r1 r); (* mov r1, r *) + end; + let rex, r2, r = rexp r2 r in + outb rex; outb op; outb (modrm r2 r) (* op r2, r *) + in + + for b = 0 to Array.length p - 1 do + let is = p.(b).bb_inss in + for i = 0 to Array.length is - 1 do + match is.(i) with + | { ri_res = l; ri_ins = `Bop (l1, op, l2) } -> + begin match op with + | Add -> arit 0x01 (regn l) (regn l1) (regn l2) + | Sub -> arit 0x29 (regn l) (regn l1) (regn l2) + | CLe -> failwith "CLe not implemented" + | CEq -> failwith "CEq not implemented" + end + | { ri_res = l; ri_ins = `Uop (Neg, l1) } -> + arit 0xf7 (regn l) 3 (regn l1) + | _ -> () + done + done; + + outb 0xc3; (* retq *) + String.concat "" (List.rev !cl) + (* Little test programs. *) let pbasic: iprog = @@ -378,6 +440,16 @@ let pbasic: iprog = } |] +(* ------------------------------------------------------------------------ *) + +let _ = + let oc = open_out "comp.bin" in + let s = pbasic |> regalloc |> movgen |> codegen in + output_string oc s; + close_out oc + +(* ------------------------------------------------------------------------ *) + let pcount: iprog = [| { bb_name = "init" ; bb_phis = [||] -- cgit 1.4.1