(* assem.ml 15-411 by Roland Flury *) (* @version $Id: assem.ml,v 1.3 2004/10/30 19:33:21 ajo Exp $ *) open Types exception MarkerError of instr (* Prints a list of instructions *) let print_assem ali = ( let print_rat = function | TEMP t -> Printf.printf "t%d" t | REGISTER t -> Printf.printf "REGISTER %d" t | STACKSLOT t -> Printf.printf "STACKSLOT %d" t in let ps = print_string in List.iter ( function | OPER(st, s, d) -> ps ("OPER("^st^", ["); List.iter print_rat s; ps "], ["; List.iter print_rat d; ps "])\n" | LIVEOPER(st, s, d) -> ps ("LIVEOPER("^st^", ["); List.iter print_rat s; ps "], ["; List.iter print_rat d; ps "])\n" | MOVE(st, s, d) -> ps ("MOVE("^st^", "); print_rat s; ps ", "; print_rat d; ps ")\n" | JUMP id -> ps ("JUMP("^id^")\n") | COMMENT id -> ps ("COMMENT("^id^")\n") | LABEL id -> ps ("LABEL "^id^":\n") ) ali ) (* Returns the list of destinations used in this instruction *) let getDst = function | OPER(_,_,d) | LIVEOPER(_,_,d) -> d | MOVE(_,_,d) -> [d] | JUMP _ | LABEL _ | COMMENT _ -> [] (* Returns the list of sources used in this instruction *) let getSrc = function | OPER(_,s,_) | LIVEOPER(_,s,_) -> s | MOVE(_,s,_) -> [s] | JUMP _ | LABEL _ | COMMENT _ -> [] (* Returns the string representing the instruction *) let getAssem = function | OPER(s,_,_) | LIVEOPER(s,_,_) | MOVE(s,_,_) -> s | JUMP s | LABEL s | COMMENT s -> s (* Returns a string representation of the instruction, using * a function mapping temps to a string *) let format (map: temp -> string) instr = let str = ref (getAssem instr) in let rec replace token list count = match list with | (TEMP head) :: tail -> let tok = token ^ (string_of_int count) in let r = Str.regexp tok in str := Str.global_replace r (map head) !str; replace token tail (count + 1) | _ :: tail -> replace token tail (count + 1) | [] -> () in match instr with | OPER _ | LIVEOPER _ | MOVE _ -> if (!str.[0] = '#') then "" else ( replace "'s" (getSrc instr) 0; replace "'d" (getDst instr) 0; "\t"^ !str ^"\n" ) | JUMP _ -> "\t"^ !str ^"\n" | LABEL _ -> !str^"\n" | COMMENT _ -> "#\n"^ !str^"\n#\n" let marker = function JUMP js -> ( let _ = Str.search_forward (Str.regexp "\t[ \t]*\\.\\([A-Za-z_0-9]+\\)") js 0 in Str.matched_group 1 js ) | LABEL ls -> ( let _ = Str.search_forward (Str.regexp "[ \t]*\\.\\([A-Za-z_0-9]+\\)[\t ]*:") ls 0 in Str.matched_group 1 ls ) | x -> raise (MarkerError x) let unconditional = function | JUMP js -> (try ( ignore(Str.search_forward (Str.regexp "jmp") js 0); true ) with Not_found -> false) | _ -> false