summaryrefslogtreecommitdiff
path: root/mips.ml
diff options
context:
space:
mode:
authorGuillaume Seguin <guillaume@segu.in>2009-01-12 03:01:29 +0100
committerGuillaume Seguin <guillaume@segu.in>2009-01-12 03:01:29 +0100
commitbb092247fc10fe76aa59294ac87e0ce2bad5b2c5 (patch)
tree165b25c3e10bf2d55bc2d54cd0e2848a0ef47ee7 /mips.ml
parent482fceb4894ca1d27099accdeb520683824defce (diff)
downloadpetitcaml-bb092247fc10fe76aa59294ac87e0ce2bad5b2c5.tar.gz
petitcaml-bb092247fc10fe76aa59294ac87e0ce2bad5b2c5.tar.bz2
[petitcaml] mips.ml : update assembly and programs format
Diffstat (limited to 'mips.ml')
-rw-r--r--mips.ml190
1 files changed, 151 insertions, 39 deletions
diff --git a/mips.ml b/mips.ml
index 74a82b8..ee0d046 100644
--- a/mips.ml
+++ b/mips.ml
@@ -8,20 +8,44 @@ type register =
| S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 | S9
| RA | GP | SP | FP
+type label = string
+type regaddress = int * register
+
+type ident_address = Alab of label | Areg of regaddress
+
type instruction =
| Move of register * register
| Li of register * int
- | La of register * string
- | Lw of register * address
- | Sw of register * address
- | Jal of string
+ | La of register * label
+ | Lw of register * regaddress
+ | Sw of register * regaddress
+ | Lw_label of register * label
+ | Sw_label of register * label
+ | Add of register * register * register
+ | Addi of register * register * int
+ | Sub of register * register * register
+ | Mul of register * register * register
+ | Div of register * register * register
+ | Neg of register * register
+ | Not of register * register
+ | And of register * register * register
+ | Or of register * register * register
+ | Seq of register * register * register
+ | Sne of register * register * register
+ | Slt of register * register * register
+ | Sle of register * register * register
+ | Sgt of register * register * register
+ | Sge of register * register * register
+ | Bgtz of register * label
+ | Blez of register * label
+ | J of label
+ | Jal of label
+ | Jalr of register * register
| Jr of register
| Syscall
- | Label of string
-
-type data =
- | Asciiz of string * string
- | Word of string * int
+ | Label of label
+ | Asciiz of label * string
+ | Word of label * int
let print_register fmt = function
| ZERO -> pp_print_string fmt "$zero"
@@ -56,42 +80,130 @@ let print_register fmt = function
| SP -> pp_print_string fmt "$sp"
| FP -> pp_print_string fmt "$fp"
+let print_regaddress fmt (offset, r) =
+ fprintf fmt "%d(%a)" offset print_register r
+
let print_instruction fmt = function
- | Move (dst, src) ->
- fprintf fmt "\tmove %a, %a\n" print_register dst print_register src
- | Li (r, i) ->
- fprintf fmt "\tli %a, %d\n" print_register r i
- | La (r, s) ->
- fprintf fmt "\tla %a, %s\n" print_register r s
- | Lw (r, a) ->
- fprintf fmt "\tlw %a, %a\n" print_register r print_address a
- | Sw (r, a) ->
- fprintf fmt "\tsw %a, %a\n" print_register r print_address a
- | Jal s ->
- fprintf fmt "\tjal %s\n" s
- | Jr r ->
- fprintf fmt "\tjr %a\n" print_register r
- | Syscall ->
- fprintf fmt "\tsyscall\n"
- | Label s ->
- fprintf fmt "%s:" s
+ | Move (dst, src) ->
+ fprintf fmt "\tmove %a, %a\n" print_register dst print_register src
+ | Li (r, i) ->
+ fprintf fmt "\tli %a, %d\n" print_register r i
+ | La (r, s) ->
+ fprintf fmt "\tla %a, %s\n" print_register r s
+ | Lw (r, a) ->
+ fprintf fmt "\tlw %a, %a\n" print_register r print_regaddress a
+ | Sw (r, a) ->
+ fprintf fmt "\tsw %a, %a\n" print_register r print_regaddress a
+ | Lw_label (r, l) ->
+ fprintf fmt "\tlw %a, %s\n" print_register r l
+ | Sw_label (r, l) ->
+ fprintf fmt "\tsw %a, %s\n" print_register r l
+ | Add (dst, src1, src2) ->
+ fprintf fmt "\tadd %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Addi (dst, src1, i) ->
+ fprintf fmt "\taddi %a, %a, %d\n" print_register dst
+ print_register src1
+ i
+ | Sub (dst, src1, src2) ->
+ fprintf fmt "\tsub %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Mul (dst, src1, src2) ->
+ fprintf fmt "\tmul %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Div (dst, src1, src2) ->
+ fprintf fmt "\tdiv %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | And (dst, src1, src2) ->
+ fprintf fmt "\tand %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Or (dst, src1, src2) ->
+ fprintf fmt "\tor %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Neg (dst, src) ->
+ fprintf fmt "\tneg %a, %a\n" print_register dst
+ print_register src
+ | Not (dst, src) ->
+ fprintf fmt "\tnot %a, %a\n" print_register dst
+ print_register src
+ | Seq (dst, src1, src2) ->
+ fprintf fmt "\tseq %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Sne (dst, src1, src2) ->
+ fprintf fmt "\tsne %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Slt (dst, src1, src2) ->
+ fprintf fmt "\tslt %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Sle (dst, src1, src2) ->
+ fprintf fmt "\tsle %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Sgt (dst, src1, src2) ->
+ fprintf fmt "\tsgt %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Sge (dst, src1, src2) ->
+ fprintf fmt "\tsge %a, %a, %a\n" print_register dst
+ print_register src1
+ print_register src2
+ | Bgtz (src, label) ->
+ fprintf fmt "\tbgtz %a, %s\n" print_register src label
+ | Blez (src, label) ->
+ fprintf fmt "\tblez %a, %s\n" print_register src label
+ | J s ->
+ fprintf fmt "\tj %s\n" s
+ | Jal s ->
+ fprintf fmt "\tjal %s\n" s
+ | Jalr (radd, rsave) ->
+ fprintf fmt "\tjalr %a, %a\n" print_register radd print_register rsave
+ | Jr r ->
+ fprintf fmt "\tjr %a\n" print_register r
+ | Syscall ->
+ fprintf fmt "\tsyscall\n"
+ | Label s ->
+ fprintf fmt "%s:" s
+ | Asciiz _
+ | Word _ -> failwith "Unreachable matching"
let print_data fmt = function
- | Asciiz (l, s) ->
- fprintf fmt "%s:\t.asciiz %S\n" l s
- | Word (l, n) ->
- fprintf fmt "%s:\t.word %d\n" l n
+ | Asciiz (l, s) ->
+ fprintf fmt "%s:\t.asciiz %s\n" l s
+ | Word (l, n) ->
+ fprintf fmt "%s:\t.word %d\n" l n
+ | _ -> failwith "Unreachable matching"
+
+type program =
+ { text : instruction list ;
+ data : instruction list }
+
+let rec filter_program = function
+ | [] -> { text = [] ; data = [] }
+ | (Asciiz (label, s))::l ->
+ let p = filter_program l
+ in
+ {p with data = (Asciiz (label, s))::p.data}
+ | (Word (label, i))::l ->
+ let p = filter_program l
+ in
+ {p with data = (Word (label, i))::p.data}
+ | instr::l ->
+ let p = filter_program l
+ in
+ {p with text = instr::p.text}
-let format_program fmt p = ""
+let format_program fmt p =
fprintf fmt "\t.text\n";
List.iter (print_instruction fmt) p.text;
fprintf fmt "\t.data\n";
List.iter (print_data fmt) p.data
-type program =
- { text : instruction list ;
- data : data list }
-
-let merge_programs p1 p2 =
- { text = p1.text @ p2.text ; data = p1.data @ p2.data }
-