stuff
This commit is contained in:
127
W1/fasto/Fasto/Mips.fs
Normal file
127
W1/fasto/Fasto/Mips.fs
Normal file
@ -0,0 +1,127 @@
|
||||
(* Types and utilities for the abstract syntax of MIPS. *)
|
||||
|
||||
module Mips
|
||||
|
||||
open AbSyn
|
||||
|
||||
type reg = RN of int | RS of string
|
||||
type imm = int
|
||||
type addr = string
|
||||
|
||||
type Instruction =
|
||||
LABEL of addr (* Angiver en label, man fx kan hoppe til *)
|
||||
| COMMENT of string (* Placerer en kommentar i assemblerkoden *)
|
||||
|
||||
| LA of reg*addr (* LA($rd,addr): $rd = addr (label) *)
|
||||
| LUI of reg*imm (* LUI($rd,imm): $rd = (imm << 16) *)
|
||||
| LW of reg*reg*imm (* LW($rd,$rs,imm): $rd = Mem[$rs + imm] *)
|
||||
| LB of reg*reg*imm (* LB($rd,$rs,imm): $rd = Mem[$rs + imm] *)
|
||||
| SW of reg*reg*imm (* SW($rw,$rm,imm): Mem[$rm + imm] = $rw *)
|
||||
| SB of reg*reg*imm (* SB($rb,$rm,imm): Mem[$rm + imm] = $rb *)
|
||||
|
||||
(* Aritmetiske instruktioner *)
|
||||
| ADD of reg*reg*reg (* ADD($rd,$rs,$rt): $rd = $rs + $rt. *)
|
||||
| ADDI of reg*reg*imm (* ADDI($rd,$rs,imm): $rd = $rs + imm *)
|
||||
| SUB of reg*reg*reg (* SUB($rd,$rs,$rt): $rd = $rs - $rt. *)
|
||||
| MUL of reg*reg*reg (* MUL($rd,$rs,$rt): $rd = $rs * $rt, no overflow. *)
|
||||
| DIV of reg*reg*reg (* DIV($rd,$rs,$rt): $rd = quotient($rd / $rs), no overflow. *)
|
||||
|
||||
(* Bitvise operatorer *)
|
||||
| AND of reg*reg*reg (* AND($rd,$rs,$rt): $rd = $rs & $rt *)
|
||||
| ANDI of reg*reg*imm (* ANDI($rd,$rs,imm): $rd = $rs & imm *)
|
||||
| OR of reg*reg*reg (* OR($rd,$rs,$rt): $rd = $rs | $rt *)
|
||||
| ORI of reg*reg*imm (* ORI($rd,$rs,imm): $rd = $rs | imm *)
|
||||
| XOR of reg*reg*reg (* XOR($rd,$rs,$rt): $rd = $rs ^ $rt *)
|
||||
| XORI of reg*reg*imm (* XORI($rd,$rs,imm): $rd = $rs ^ imm *)
|
||||
|
||||
(* Bit-shifting *)
|
||||
| SLL of reg*reg*imm (* SLL($rd,$rs,imm): $rd = $rs << imm *)
|
||||
| SRA of reg*reg*imm (* SRA($rd,$rs,imm): $rd = $rs >> imm *)
|
||||
|
||||
(* Instruktioner til sammenligning *)
|
||||
| SLT of reg*reg*reg (* SLT($rd,$rs,$rt): $rd = $rs < $rt *)
|
||||
| SLTI of reg*reg*imm (* SLTI($rd,$rs,imm): $rd = $rs < imm *)
|
||||
| BEQ of reg*reg*addr (* BEQ($rs,$rt,addr): if ($rs == $rd) goto(addr) *)
|
||||
| BNE of reg*reg*addr (* BNE($rs,$rt,addr): if ($rs != $rd) goto(addr) *)
|
||||
| BGEZ of reg*addr (* BGEZ($rs,addr): if ($rs >= $0) goto(addr) *)
|
||||
| J of addr (* J(addr): goto(addr) *)
|
||||
| JR of reg * reg list (* JR($rd,regs): goto($rd) *)
|
||||
| JAL of addr* reg list (* JAL(addr,regs): $RA = $PC; goto(addr) *)
|
||||
| NOP
|
||||
| SYSCALL (* Udfører det systemkald som er nævnt i $2 *)
|
||||
|
||||
(* Angiver direktiverne .globl, .text, .data, .space, ascii, .asciiz, .align *)
|
||||
| GLOBL of addr
|
||||
| TEXT of addr
|
||||
| DATA of addr
|
||||
| SPACE of int
|
||||
| ASCII of string
|
||||
| ASCIIZ of string
|
||||
| ALIGN of int
|
||||
|
||||
(* Diverse pseudo-instruktioner *)
|
||||
let MOVE (rd,rs) = ORI (rd, rs, 0) (* MOVE($rd,$rs): $rd = $rs *)
|
||||
let LI (rd,imm) = ORI (rd, RN 0, imm) (* LI($rd,imm): $rd = imm *)
|
||||
let SUBI (rd, rs, imm) = ADDI (rd, rs, -imm)
|
||||
|
||||
type Prog = Instruction list
|
||||
|
||||
(* Pretty-print a list of MIPS instructions in the
|
||||
format accepted by the MARS MIPS simulator. *)
|
||||
let rec ppMipsProg instructions =
|
||||
String.concat "\n" (List.map ppMips instructions)
|
||||
|
||||
(* Pretty-print a single MIPS instruction for .asm output *)
|
||||
and ppMips inst =
|
||||
match inst with
|
||||
| LABEL l -> l + ":"
|
||||
| COMMENT s -> "# " + s
|
||||
|
||||
| LA (rt,l) -> "\tla\t" + ppReg rt + ", " + l
|
||||
| LUI (rt,v) -> "\tlui\t" + ppReg rt + ", " + imm2str v
|
||||
| LW (rd,rs,v) -> "\tlw\t" + ppReg rd + ", " + imm2str v + "(" + ppReg rs + ")"
|
||||
| LB (rd,rs,v) -> "\tlb\t" + ppReg rd + ", " + imm2str v + "(" + ppReg rs + ")"
|
||||
| SW (rd,rs,v) -> "\tsw\t" + ppReg rd + ", " + imm2str v + "(" + ppReg rs + ")"
|
||||
| SB (rd,rs,v) -> "\tsb\t" + ppReg rd + ", " + imm2str v + "(" + ppReg rs + ")"
|
||||
|
||||
| ADD (rd,rs,rt) -> "\tadd\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| ADDI (rd,rs,v) -> "\taddi\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
| SUB (rd,rs,rt) -> "\tsub\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| MUL (rd,rs,rt) -> "\tmul\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| DIV (rd,rs,rt) -> "\tdiv\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
|
||||
| AND (rd,rs,rt) -> "\tand\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| ANDI (rd,rs,v) -> "\tandi\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
| OR (rd,rs,rt) -> "\tor\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| ORI (rd,rs,v) -> "\tori\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
| XOR (rd,rs,rt) -> "\txor\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| XORI (rd,rs,v) -> "\txori\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
|
||||
| SLL (rd,rt,v) -> "\tsll\t" + ppReg rd + ", " + ppReg rt + ", " + imm2str v
|
||||
| SRA (rd,rt,v) -> "\tsra\t" + ppReg rd + ", " + ppReg rt + ", " + imm2str v
|
||||
|
||||
| SLT (rd,rs,rt) -> "\tslt\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| SLTI (rd,rs,v) -> "\tslti\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
| BEQ (rs,rt,l) -> "\tbeq\t" + ppReg rs + ", " + ppReg rt + ", " + l
|
||||
| BNE (rs,rt,l) -> "\tbne\t" + ppReg rs + ", " + ppReg rt + ", " + l
|
||||
| BGEZ (rs,l) -> "\tbgez\t" + ppReg rs + ", " + l
|
||||
| J l -> "\tj\t" + l
|
||||
| JAL (l,argRegs) -> "\tjal\t" + l
|
||||
| JR (r,resRegs) -> "\tjr\t" + ppReg r
|
||||
| NOP -> "\tnop"
|
||||
| SYSCALL -> "\tsyscall"
|
||||
|
||||
| GLOBL s -> "\t.globl\t" + s
|
||||
| TEXT s -> "\t.text\t" + s
|
||||
| DATA s -> "\t.data\t" + s
|
||||
| SPACE s -> "\t.space\t" + string s
|
||||
| ASCII s -> "\t.ascii\t\"" + toCString s + "\""
|
||||
| ASCIIZ s -> "\t.asciiz\t\"" + toCString s + "\""
|
||||
| ALIGN s -> "\t.align\t" + string s
|
||||
|
||||
and ppReg r =
|
||||
match r with
|
||||
| RN n -> "$" + string n
|
||||
| RS s -> s
|
||||
|
||||
and imm2str (i:imm) = string i (* maybe add some sanity checks here *)
|
Reference in New Issue
Block a user