let int_size = 1 let ptr_size = 2 let alignment = None type opaccs = | Mul | DivuModu type op1 = | Cmpl | Inc type op2 = | Add | Addc | Sub | And | Or | Xor let print_opaccs = function | Mul -> "mul" | DivuModu -> "divu" let print_op1 = function | Cmpl -> "cmpl" | Inc -> "inc" let print_op2 = function | Add -> "add" | Addc -> "addc" | Sub -> "sub" | And -> "and" | Or -> "or" | Xor -> "xor" module Eval (Val : Value.S) = struct let eval_int_mul size i1 i2 = let module Int = IntValue.Make (struct let size = 2 * size end) in match Int.break (Int.mul i1 i2) 2 with | res1 :: res2 :: _ -> (Val.of_int_repr res1, Val.of_int_repr res2) | _ -> assert false (* should be impossible *) let eval_mul v1 v2 = if Val.is_int v1 && Val.is_int v2 then eval_int_mul Val.int_size (Val.to_int_repr v1) (Val.to_int_repr v2) else (Val.undef, Val.undef) let opaccs op v1 v2 = match op with | Mul -> eval_mul v1 v2 | DivuModu -> (Val.divu v1 v2, Val.modulou v1 v2) let op1 = function | Cmpl -> Val.cmpl | Inc -> Val.succ let op2 carry op2 v1 v2 = match op2 with | Add -> Val.add_and_of v1 v2 | Addc -> let (res1, of1) = Val.add_and_of v1 v2 in let (res2, of2) = Val.add_and_of res1 carry in (res2, Val.or_op of1 of2) | Sub -> let (res1, uf1) = Val.sub_and_uf v1 v2 in let (res2, uf2) = Val.sub_and_uf res1 carry in (res2, Val.or_op uf1 uf2) | And -> (Val.and_op v1 v2, carry) | Or -> (Val.or_op v1 v2, carry) | Xor -> (Val.xor v1 v2, carry) end type register = int let compare_reg = Pervasives.compare let eq_reg r1 r2 = r1 = r2 module OrdReg = struct type t = register let compare = compare_reg end module RegisterSet = Set.Make (OrdReg) module RegisterMap = Map.Make (OrdReg) let r00 = 0 let r01 = 1 let r02 = 2 let r03 = 3 let r04 = 4 let r05 = 5 let r06 = 6 let r07 = 7 let r10 = 8 let r11 = 9 let r12 = 10 let r13 = 11 let r14 = 12 let r15 = 13 let r16 = 14 let r17 = 15 let r20 = 16 let r21 = 17 let r22 = 18 let r23 = 19 let r24 = 20 let r25 = 21 let r26 = 22 let r27 = 23 let r30 = 24 let r31 = 25 let r32 = 26 let r33 = 27 let r34 = 28 let r35 = 29 let r36 = 30 let r37 = 31 let a = 224 let b = 240 let dpl = 130 let dph = 131 let carry = -1 (* only used for the liveness analysis. *) let print_register = function | 0 -> "R00" | 1 -> "R01" | 2 -> "R02" | 3 -> "R03" | 4 -> "R04" | 5 -> "R05" | 6 -> "R06" | 7 -> "R07" | 8 -> "R10" | 9 -> "R11" | 10 -> "R12" | 11 -> "R13" | 12 -> "R14" | 13 -> "R15" | 14 -> "R16" | 15 -> "R17" | 16 -> "R20" | 17 -> "R21" | 18 -> "R22" | 19 -> "R23" | 20 -> "R24" | 21 -> "R25" | 22 -> "R26" | 23 -> "R27" | 24 -> "R30" | 25 -> "R31" | 26 -> "R32" | 27 -> "R33" | 28 -> "R34" | 29 -> "R35" | 30 -> "R36" | 31 -> "R37" | 224 -> "A" | 240 -> "B" | 130 -> "DPL" | 131 -> "DPH" | _ -> assert false (* impossible *) let sst = r10 let st0 = r02 let st1 = r03 let st2 = r04 let st3 = r05 let sts = [st0 ; st1 ; st2 ; st3] let spl = r06 let sph = r07 let rets = [dpl ; dph ; r00 ; r01] let spl_addr = spl let spl_init = 255 let sph_addr = sph let sph_init = 255 let isp_addr = 129 let isp_init = 47 let set_of_list rl = List.fold_right RegisterSet.add rl RegisterSet.empty let list_of_set rs = RegisterSet.fold (fun r l -> r :: l) rs [] let registers = set_of_list [r00 ; r01 ; r02 ; r03 ; r04 ; r05 ; r06 ; r07 ; r10 ; r11 ; r12 ; r13 ; r14 ; r15 ; r16 ; r17 ; r20 ; r21 ; r22 ; r23 ; r24 ; r25 ; r26 ; r27 ; r30 ; r31 ; r32 ; r33 ; r34 ; r35 ; r36 ; r37 ; a ; b ; dpl ; dph ; spl ; sph ; st0 ; st1 ; sst] let forbidden = set_of_list [a ; b ; dpl ; dph ; spl ; sph ; st0 ; st1 ; st2 ; st3 ; sst] let parameters = let params = set_of_list [r30 ; r31 ; r32 ; r33 ; r34 ; r35 ; r36 ; r37] in list_of_set (RegisterSet.diff params forbidden) let callee_saved = RegisterSet.diff (set_of_list [r20 ; r21 ; r22 ; r23 ; r24 ; r25 ; r26 ; r27]) forbidden let caller_saved = RegisterSet.diff (RegisterSet.diff registers callee_saved) forbidden let allocatable = RegisterSet.diff registers forbidden let reg_addr r = `DIRECT (BitVectors.vect_of_int r `Eight) (* External RAM size *) let ext_ram_size = MiscPottier.pow 2 16 (* Internal RAM size *) let int_ram_size = MiscPottier.pow 2 8