This repository has been archived on 2022-12-27. You can view files and clone it, but cannot push or open issues or pull requests.
compilateurMIPS/mips.ml
Mylloon af7799ea2c
* add neg
* change fmt_instr
2022-12-08 19:54:17 +01:00

158 lines
4 KiB
OCaml

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 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
| Neg 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
type asm =
{ text : instr list
; data : decl list
}
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
| Label _ -> ""
| _ as i ->
Printf.sprintf " "
^
(match i with
| 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)
| Neg (r, a) -> Printf.sprintf "neg %s, %s" (fmt_reg r) (fmt_reg a)
| 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 -> 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
"%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
;;