===== Strumenti per l'analisi del codice D-RISC ===== Ciò che viene presentato in questa pagina è //sperimentale//. Potrebbero esserci errori e si potrebbero verificare malfunzionamenti. Se foste interessati a contribuire (testing, debugging, sviluppo) potete scaricare e modificare il codice a vostro piacimento. Se apportate modifiche significative, inviate il codice modificato al docente che lo renderà disponibile su questa pagina. E' disponibile una versione che corregge parte dei problemi della versione originale discussa nel seguito (realizzata da Nicola Corti). La versione include un [[file_asm.ml|asm.ml]] e un [[file_drisc.ml|drisc.ml]] modificati ed espansi. La documentazione di questa versione estesa è disponibile su [[http://backus.di.unipi.it/~marcod/AE1011/Corti/doc/index.html|questo]] link. ==== Documentazione ==== La documentazione generata con ocamldoc si trova su [[http://backus.di.unipi.it/~marcod/AE1011/DocDRISCocaml/|questa pagina]]. ==== Analisi delle dipendenze ==== Il codice che segue serve a trovare le dipendenze logiche in codice D-RISC. Il software funziona come dovuto su assembler privo di salti (ovvero non tiene conto dell'effetto dei salti). Il software è realizzato in Ocaml. Le istruzioni assembler sono rappresentate come indicato nella definizione dei tipi (statement "type" nel codice Ocaml). Insieme al codice sono definite un certo numero di funzioni per il pretty printing di codice e dipendenze. Per utilizzare il codice, seguite questi passi. **Codice D-RISC** Scrivere un file "prog.ml" con la definizione del programma da utilizzare, secondo le convenzioni della grammatica definita nel file **asm.ml** Ad esempio, possiamo scrivere nel file: let p = [ LabInstr(LabLab("loop"),LD(Reg(5),Reg(1),Reg(10))); Instr(LD(Reg(6),Reg(1),Reg(11))); Instr(ADD(Reg(10),Reg(11),Reg(12))); Instr(ST(Reg(7),Reg(1),Reg(12))); Instr(INC(Reg(1))); Instr(IFLE(Reg(1),Reg(2),LabLab("loop"))); Instr(END); ];; **Interprete** Lanciate un interprete ocaml da riga di comando. Caricate il file [[asmsource|asm.ml]] con il comando #use "asm.ml";;(il simbolo # //non è// il prompt dell'interprete, ma il segno che state inserendo una direttiva). Quindi caricate il programma, con il comando #use "prog.ml";;. **Uso del tool** A questo punto potete: * stampare il programma in formato leggibile (funzione **pp_prog** con parametri: 1) indirizzo della prima istruzione (normalmente 0) e 2) variabile con la rappresentazione del programma) * vedere le dipendenze logiche (funzione **data_deps** con 1 parametro: variabile con la rappresentazione del programma) * stampare le dipendenze logiche in forma leggibile (funzione **pp_deps* con 1 parametro: lista delle dipendenze Di seguito riportiamo un dump della sessione a terminale che mostra le dipendenze del codice in **prog.ml** marcod@macuntu:~/Documents/Didattica/Architetture/Sim$ ocaml Objective Caml version 3.12.0 # #use "asm.ml";; type reg = Reg of int type label = LabOff of int | LabLab of string type const = Const of int type asm = ADD of reg * reg * reg | SUB of reg * reg * reg | MUL of reg * reg * reg | DIV of reg * reg * reg | ADDI of reg * const * reg | SUBI of reg * const * reg | INC of reg | DEC of reg | LD of reg * reg * reg | LDI of reg * const * reg | ST of reg * reg * reg | STI of reg * const * reg | CALL of reg * reg | GOTOR of reg | GOTOL of label | IFLEQ of reg * reg * label | IFLE of reg * reg * label | IFGEQ of reg * reg * label | IFGE of reg * reg * label | IFEQ of reg * reg * label | IFNEQ of reg * reg * label | END type instruction = Instr of asm | LabInstr of label * asm val domain : asm -> reg list = val codomain : asm -> reg list = val intersect : 'a list -> 'a list -> 'a list = val iu_instruction : asm -> bool = type datadep = NoDataDep | DataDep of int * asm * int * asm * reg list * int * int val delab : instruction -> asm = val data_dep_i : int -> int -> instruction -> instruction -> int -> int -> datadep = val loadsinsequence : instruction list -> int -> int -> bool = val data_deps : instruction list -> datadep list = val bernstein : asm -> asm -> bool = val pp_reg : reg -> unit = val pp_regs : reg list -> unit = val pp_reg_set : int ref array -> unit = val pp_mem : int ref array -> unit = val pp_lab : label -> unit = val pp_const : const -> unit = val pp_asm : asm -> unit = val pp_instr : int -> instruction -> unit = val pp_prog : int -> instruction list -> unit = val pp_program : instruction list -> unit = val pp_dd : datadep -> unit = val pp_deps : datadep list -> unit = val prog_to_asm : instruction list -> asm list = type assoc = Ass of string * int val hasKey : string -> assoc list -> bool = val valueOfKey : string -> assoc list -> int = type penv = Penv of int ref * int ref array * int ref array * assoc list val dump : penv -> unit = val exec_i : asm -> penv -> unit = val labels : instruction list -> int -> assoc list = # #use "prog.ml";; val p : instruction list = [LabInstr (LabLab "loop", LD (Reg 5, Reg 1, Reg 10)); Instr (LD (Reg 6, Reg 1, Reg 11)); Instr (ADD (Reg 10, Reg 11, Reg 12)); Instr (ST (Reg 7, Reg 1, Reg 12)); Instr (INC (Reg 1)); Instr (IFLE (Reg 1, Reg 2, LabLab "loop")); Instr END] # pp_prog 0 p;; 0. loop :LOAD R_5 R_1 R_10 1. LOAD R_6 R_1 R_11 2. ADD R_10 R_11 R_12 3. STORE R_7 R_1 R_12 4. INC R_1 5. IF< R_1 R_2 loop 6. END - : unit = () # data_deps p;; - : datadep list = [DataDep (2, ADD (Reg 10, Reg 11, Reg 12), 3, ST (Reg 7, Reg 1, Reg 12), [Reg 12], 1, 2); DataDep (4, INC (Reg 1), 5, IFLE (Reg 1, Reg 2, LabLab "loop"), [Reg 1], 1, 1)] # pp_deps (data_deps p);; DD:: 2. ADD R_10 R_11 R_12 ==>> 3. STORE R_7 R_1 R_12 (d=1 N=2) due to reg(s) R_12 DD:: 4. INC R_1 ==>> 5. IF< R_1 R_2 loop (d=1 N=1) due to reg(s) R_1 - : unit = () # #quit;; marcod@macuntu:~/Documents/Didattica/Architetture/Sim$ exit exit Script done on Fri 08 Apr 2011 03:06:31 PM CEST marcod@macuntu:~/Documents/Didattica/Architetture/Sim$ ==== Esecuzione di codice ===== Per eseguire del codice DRISC, utilizzate gli strumenti (New: Dicembre 2011) disponibili su [[http://backus.di.unipi.it/~marcod/wiki/doku.php?id=drisc|questa]] pagina.