From 5c44aecd0c5c74cf85bde6f4827196eccce85b8e Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Wed, 25 Mar 2015 14:32:52 -0400 Subject: more codegen --- lo2.ml | 65 +++++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/lo2.ml b/lo2.ml index 6331185..bc69124 100644 --- a/lo2.ml +++ b/lo2.ml @@ -396,29 +396,49 @@ let codegen (p: mprog): string = 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 + let move l l1 = match l, l1 with + | (LReg _ as r), LCon k -> + let rec outw i x = + if i = 0 then () else + (outb (x land 0xff); outw (i-1) (x lsr 8)) in + let rex, r, m = rexp 0 (regn r) in + outb rex; outb 0xc7; outb (modrm r m); outw 4 k + | (LReg _ as r), (LReg _ as r1) -> + let rex, r1, r = rexp (regn r1) (regn r) in + outb rex; outb 0x89; outb (modrm r1 r) + | (LReg _ as r), LSpill s -> assert (s<256/8); + let rex, r, m = rexp (regn r) 5 in + outb rex; outb 0x8b; outb (modrm ~md:1 r m); outb (s*4) + | LSpill s, (LReg _ as r) -> assert (s<256/8); + let rex, r, m = rexp (regn r) 5 in + outb rex; outb 0x89; outb (modrm ~md:1 r m); outb (s*4) + | _ -> failwith "invalid move" in + + let oins op r m = + let rex, r, m = rexp r m in + outb rex; outb op; outb (modrm r m) 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) } -> + if l1 <> l then + move l l1; begin match op with - | Add -> arit 0x01 (regn l) (regn l1) (regn l2) - | Sub -> arit 0x29 (regn l) (regn l1) (regn l2) + | Add -> oins 0x01 (regn l2) (regn l) + | Sub -> oins 0x29 (regn l2) (regn l) | 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) - | _ -> () + if l <> l1 then + move l l1; + oins 0xf7 3 (regn l) + | { ri_res = l; ri_ins = `Mov l1 } -> + move l l1 + | { ri_res = l; ri_ins = `Con k } -> + move l (LCon k) done done; @@ -440,16 +460,6 @@ 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 = [||] @@ -514,3 +524,14 @@ let pspill: iprog = ; bb_jmp = `Brz (IRIns (0, 13), -1, -1) } |] + + +(* ------------------------------------------------------------------------ *) + +let _ = + let oc = open_out "comp.bin" in + let s = pspill |> regalloc |> movgen |> codegen in + output_string oc s; + close_out oc + +(* ------------------------------------------------------------------------ *) -- cgit 1.4.1