mips-cc

A little C compiler
git clone git@git.mpah.dev/mips-cc.git
Log | Files | Refs | README

mips.ml (3983B)


      1 type reg =
      2   | Zero
      3   | SP
      4   | RA
      5   | FP
      6   | V0
      7   | A0
      8   | A1
      9   | T0
     10   | T1
     11   | F0
     12 
     13 type label = string
     14 type loc =
     15   | Lbl of label
     16   | Mem of reg * int
     17 
     18 type instr =
     19   | Label of label
     20   | Li    of reg * int
     21   | Lis   of reg * float
     22   | La    of reg * loc
     23   | Sw    of reg * loc
     24   | Lw    of reg * loc
     25   | Sb    of reg * loc
     26   | Lb    of reg * loc
     27   | Move  of reg * reg
     28   | Addi  of reg * reg * int
     29   | Adds   of reg * reg * reg
     30   | Add   of reg * reg * reg
     31   | Sub   of reg * reg * reg
     32   | Mul   of reg * reg * reg
     33   | Div   of reg * reg * reg
     34   | Syscall
     35   | B     of label
     36   | Beqz  of reg * label
     37   | Jal   of label
     38   | Jr    of reg
     39   | Mfhi  of reg
     40   | Mflo  of reg
     41   | Seq   of reg * reg * reg
     42   | Sne   of reg * reg * reg
     43   | Sge   of reg * reg * reg
     44   | Sgt   of reg * reg * reg
     45   | Sle   of reg * reg * reg
     46   | Slt   of reg * reg * reg
     47   | Xor   of reg * reg * reg
     48   | Or    of reg * reg * reg
     49   | And   of reg * reg * reg
     50 
     51 type directive =
     52   | Asciiz of string
     53 
     54 type decl = label * directive
     55 
     56 type asm = { text: instr list ; data: decl list }
     57 
     58 module Syscall = struct
     59   let print_int = 1
     60   let print_str = 4
     61   let read_int  = 5
     62   let read_str  = 8
     63   let sbrk      = 9
     64 end
     65 
     66 let ps = Printf.sprintf
     67 
     68 let fmt_reg = function
     69   | Zero -> "$zero"
     70   | SP   -> "$sp"
     71   | FP   -> "$fp"
     72   | RA   -> "$ra"
     73   | V0   -> "$v0"
     74   | A0   -> "$a0"
     75   | A1   -> "$a1"
     76   | T0   -> "$t0"
     77   | T1   -> "$t1"
     78   | F0   -> "$f0"
     79 
     80 let fmt_loc = function
     81   | Lbl (l)    -> l
     82   | Mem (r, o) -> ps "%d(%s)" o (fmt_reg r)
     83 
     84 let fmt_instr = function
     85   | Label (l)        -> ps "%s:" l
     86   | Li (r, i)        -> ps "  li %s, %d" (fmt_reg r) i
     87   | Lis (r, f)       -> ps "  li.s %s, %f" (fmt_reg r) f
     88   | La (r, a)        -> ps "  la %s, %s" (fmt_reg r) (fmt_loc a)
     89   | Sw (r, a)        -> ps "  sw %s, %s" (fmt_reg r) (fmt_loc a)
     90   | Lw (r, a)        -> ps "  lw %s, %s" (fmt_reg r) (fmt_loc a)
     91   | Sb (r, a)        -> ps "  sb %s, %s" (fmt_reg r) (fmt_loc a)
     92   | Lb (r, a)        -> ps "  lb %s, %s" (fmt_reg r) (fmt_loc a)
     93   | Move (rd, rs)    -> ps "  move %s, %s" (fmt_reg rd) (fmt_reg rs)
     94   | Addi (rd, rs, i) -> ps "  addi %s, %s, %d" (fmt_reg rd) (fmt_reg rs) i
     95   | Add (rd, rs, rt) -> ps "  add %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
     96   | Sub (rd, rs, rt) -> ps "  sub %s, %s, %s" (fmt_reg rd) (fmt_reg rt) (fmt_reg rs)
     97   | Adds (rd, rs, rt) -> ps " add.s %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
     98   | Mul (rd, rs, rt) -> ps "  mul %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
     99   | Div (rd, rs, rt) -> ps "  div %s, %s, %s" (fmt_reg rd) (fmt_reg rt) (fmt_reg rs)
    100   | Syscall          -> ps "  syscall"
    101   | B (l)            -> ps "  b %s" l
    102   | Beqz (r, l)      -> ps "  beqz %s, %s" (fmt_reg r) l
    103   | Jal (l)          -> ps "  jal %s" l
    104   | Jr (r)           -> ps "  jr %s" (fmt_reg r)
    105   | Mfhi (r)         -> ps "  mfhi %s" (fmt_reg r)
    106   | Mflo (r)         -> ps "  mflo %s" (fmt_reg r)
    107   | Seq (rd, rs, rt) -> ps "  seq %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    108   | Sne (rd, rs, rt) -> ps "  sne %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    109   | Sge (rd, rt, rs) -> ps "  sge %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    110   | Sgt (rd, rt, rs) -> ps "  sgt %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    111   | Sle (rd, rt, rs) -> ps "  sle %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    112   | Slt (rd, rt, rs) -> ps "  slt %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    113   | Xor (rd, rs, rt) -> ps "  xor %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    114   | Or (rd, rs, rt)  -> ps "  or %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    115   | And (rd, rs, rt) -> ps "  and %s, %s, %s" (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
    116 
    117 
    118 
    119 let fmt_dir = function
    120   | Asciiz (s) -> ps ".asciiz \"%s\"" s
    121 
    122 let print_asm oc asm =
    123   Printf.fprintf oc ".text\n.globl main\n" ;
    124   List.iter (fun i -> Printf.fprintf oc "%s\n" (fmt_instr i)) asm.text ;
    125   Printf.fprintf oc "\n.data\n" ;
    126   List.iter (fun (l, d) -> Printf.fprintf oc "%s: %s\n" l (fmt_dir d)) asm.data