158 lines
4 KiB
OCaml
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
|
|
;;
|