diff --git a/mips.ml b/mips.ml index f6d822c..31d8b33 100644 --- a/mips.ml +++ b/mips.ml @@ -1,6 +1,58 @@ -type reg = V0 +type reg = + | Zero (* Toujours à zéro *) + | V0 (* Valeurs de retours *) + | V1 (* .................. *) + | A0 (* Premiers arguments des fonctions *) + | A1 (* ................................ *) + | A2 (* ................................ *) + | A3 (* ................................ *) + | T0 (* Registres temporaires *) + | T1 (* ..................... *) + | T2 (* ..................... *) + | T3 (* ..................... *) + | T4 (* ..................... *) + | T5 (* ..................... *) + | T6 (* ..................... *) + | T7 (* ..................... *) + | T8 (* ..................... *) + | T9 (* ..................... *) + | S0 (* Registres sauvegardés *) + | S1 (* ..................... *) + | S2 (* ..................... *) + | S3 (* ..................... *) + | S4 (* ..................... *) + | S5 (* ..................... *) + | S6 (* ..................... *) + | S7 (* ..................... *) + | GP (* Global pointer *) + | SP (* Stack pointer *) + | FP (* Frame pointer *) + | RA (* Adresse de retour *) + type label = string -type instr = Li of reg * int + +type loc = + | Lbl of label + | Mem of reg * int + +type instr = + | Label of label + | Li of reg * int + | La of reg * loc + | Sw of reg * loc + | Lw of reg * loc + | Sb of reg * loc + | Lb of reg * loc + | Move of reg * reg + | Addi of reg * reg * int + | Add of reg * reg * reg + | Mul of reg * reg * reg + | Syscall + | B of label + | Beqz of reg * label + | Jal of label + | Jr of reg + type directive = Asciiz of string type decl = label * directive @@ -9,24 +61,91 @@ type asm = ; data : decl list } -let ps = Printf.sprintf (* alias raccourci *) +module Syscall = struct + let print_int = 1 + let print_float = 2 + let print_double = 3 + let print_str = 4 + let read_int = 5 + let read_float = 6 + let read_double = 7 + let read_str = 8 + let sbrk = 9 + let exit = 10 +end let fmt_reg = function + | Zero -> "$zero" | V0 -> "$v0" + | V1 -> "$v1" + | A0 -> "$a0" + | A1 -> "$a1" + | A2 -> "$a2" + | A3 -> "$a3" + | T0 -> "$t0" + | T1 -> "$t1" + | T2 -> "$t2" + | T3 -> "$t3" + | T4 -> "$t4" + | T5 -> "$t5" + | T6 -> "$t6" + | T7 -> "$t7" + | T8 -> "$t8" + | T9 -> "$t9" + | S0 -> "$s0" + | S1 -> "$s1" + | S2 -> "$s2" + | S3 -> "$s3" + | S4 -> "$s4" + | S5 -> "$s5" + | S6 -> "$s6" + | S7 -> "$s7" + | GP -> "$gp" + | SP -> "$sp" + | FP -> "$fp" + | RA -> "$ra" +;; + +let fmt_loc = function + | Lbl l -> l + | Mem (r, o) -> Printf.sprintf "%d(%s)" o (fmt_reg r) ;; let fmt_instr = function - | Li (r, i) -> ps " li %s, %d" (fmt_reg r) i + | Label l -> Printf.sprintf "%s:" l + | Li (r, i) -> Printf.sprintf " li %s, %d" (fmt_reg r) i + | La (r, a) -> Printf.sprintf " la %s, %s" (fmt_reg r) (fmt_loc a) + | Sw (r, a) -> Printf.sprintf " sw %s, %s" (fmt_reg r) (fmt_loc a) + | Lw (r, a) -> Printf.sprintf " lw %s, %s" (fmt_reg r) (fmt_loc a) + | Sb (r, a) -> Printf.sprintf " sb %s, %s" (fmt_reg r) (fmt_loc a) + | Lb (r, a) -> Printf.sprintf " lb %s, %s" (fmt_reg r) (fmt_loc a) + | Move (rd, rs) -> Printf.sprintf " move %s, %s" (fmt_reg rd) (fmt_reg rs) + | Addi (rd, rs, i) -> Printf.sprintf " addi %s, %s, %d" (fmt_reg rd) (fmt_reg rs) i + | Add (rd, rs, rt) -> + Printf.sprintf " add %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) + | Mul (rd, rs, rt) -> + Printf.sprintf " mul %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) + | Syscall -> Printf.sprintf " syscall" + | B l -> Printf.sprintf " b %s" l + | Beqz (r, l) -> Printf.sprintf " beqz %s, %s" (fmt_reg r) l + | Jal l -> Printf.sprintf " jal %s" l + | Jr r -> Printf.sprintf " jr %s" (fmt_reg r) ;; let fmt_dir = function - | Asciiz s -> ps ".asciiz \"%s\"" s + | Asciiz s -> Printf.sprintf ".asciiz \"%s\"" s ;; let emit oc asm = Printf.fprintf oc ".text\n.globl main\nmain:\n"; List.iter (fun i -> Printf.fprintf oc "%s\n" (fmt_instr i)) asm.text; - Printf.fprintf oc " move $a0, $v0\n li $v0, 1\n syscall\n jr $ra\n"; + Printf.fprintf + oc + "%s\n%s\n%s\n%s\n" + (fmt_instr (Move (A0, V0))) + (fmt_instr (Li (V0, 1))) + (fmt_instr Syscall) + (fmt_instr (Jr RA)); Printf.fprintf oc "\n.data\n"; List.iter (fun (l, d) -> Printf.fprintf oc "%s: %s\n" l (fmt_dir d)) asm.data ;;