diff --git a/ass1/horner.asm b/ass1/horner.asm index d159b34..8f8eafa 100644 --- a/ass1/horner.asm +++ b/ass1/horner.asm @@ -1,6 +1,9 @@ -poly START 0 -start LDT x4 - LDS x +poly START 16 +p BYTE X'EF' + ADD #34 +start +LDT x4, X +x4 WORD 1 + +LDS @x MULR S, T LDA x3 ADDR T, A . do sedaj izračunano (1x + 2) @@ -8,7 +11,6 @@ start LDT x4 LDT x2 MULR S, A ADDR T, A .do sedaj izračunano ((1x+2)x + 3) - LDT x1 MULR S, A ADDR T, A .do sedaj izračunano (((1x+2)x + 3)x + 4) @@ -21,11 +23,11 @@ start LDT x4 STA rez halt J halt - END start + .polinom -x4 WORD 1 + x3 WORD 2 x2 WORD 3 x1 WORD 4 @@ -35,4 +37,6 @@ x0 WORD 5 x WORD 2 .rezultat -rez RESW 1 \ No newline at end of file +rez RESW 1 + + END start \ No newline at end of file diff --git a/ass1/horner.log b/ass1/horner.log index 7f6c11d..9b1511f 100644 --- a/ass1/horner.log +++ b/ass1/horner.log @@ -1,21 +1,24 @@ ***** Section ***** -Stats: size=61 blocks=61 symbols=10 literals=0 relocations=0 +Stats: size=67 blocks=67 symbols=11 literals=0 relocations=2 Blocks name start size #ins #dir #sto - 00000 0003D 16 8 1 + 00010 00043 17 9 1 Symbols name hex dec scope kind type description - halt 000025 37 local relative code label - poly 000000 0 exported relative code label - rez 00003A 58 local relative data label - start 000000 0 local relative code label - x 000037 55 local relative data label - x0 000034 52 local relative data label - x1 000031 49 local relative data label - x2 00002E 46 local relative data label - x3 00002B 43 local relative data label - x4 000028 40 local relative data label + halt 00003E 62 local relative code label + p 000010 16 local relative data label + poly 000010 16 exported relative code label + rez 000050 80 local relative data label + start 000014 20 local relative code label + x 00004D 77 local relative data label + x0 00004A 74 local relative data label + x1 000047 71 local relative data label + x2 000044 68 local relative data label + x3 000041 65 local relative data label + x4 000018 24 local relative data label Literals label definition Relocations address length flag symbol + 00015 5 + 0001C 5 diff --git a/ass1/horner.lst b/ass1/horner.lst index 4bb467e..218602c 100644 --- a/ass1/horner.lst +++ b/ass1/horner.lst @@ -1,38 +1,42 @@ -00000 poly START 0 -00000 772025 start LDT x4 -00003 6F2031 LDS x -00006 9845 MULR S,T -00008 032020 LDA x3 -0000B 9050 ADDR T,A . do sedaj izračunano (1x + 2) +00010 poly START 16 +00010 EF p BYTE X'EF' +00011 190022 ADD #34 +00014 77900018 start +LDT x4,X +00018 000001 x4 WORD 1 +0001B 6E10004D +LDS @x +0001F 9845 MULR S,T +00021 03201D LDA x3 +00024 9050 ADDR T,A . do sedaj izračunano (1x + 2) -0000D 77201E LDT x2 -00010 9840 MULR S,A -00012 9050 ADDR T,A . do sedaj izračunano ((1x+2)x + 3) +00026 77201B LDT x2 +00029 9840 MULR S,A +0002B 9050 ADDR T,A . do sedaj izračunano ((1x+2)x + 3) +0002D 772017 LDT x1 +00030 9840 MULR S,A +00032 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4) -00014 77201A LDT x1 -00017 9840 MULR S,A -00019 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4) +00034 772013 LDT x0 +00037 9840 MULR S,A +00039 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)x + 5 -0001B 772016 LDT x0 -0001E 9840 MULR S,A -00020 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)x + 5 + . fullline comment +0003B 0F2012 STA rez +0003E 3F2FFD halt J halt -00022 0F2015 STA rez - -00025 3F2FFD halt J halt -00028 END start . polinom -00028 000001 x4 WORD 1 -0002B 000002 x3 WORD 2 -0002E 000003 x2 WORD 3 -00031 000004 x1 WORD 4 -00034 000005 x0 WORD 5 + +00041 000002 x3 WORD 2 +00044 000003 x2 WORD 3 +00047 000004 x1 WORD 4 +0004A 000005 x0 WORD 5 . tocka -00037 000002 x WORD 2 +0004D 000002 x WORD 2 . rezultat -0003A 000000 rez RESW 1 +00050 000000 rez RESW 1 + +00053 END start diff --git a/ass1/horner.obj b/ass1/horner.obj index 5c396f6..3fcdb26 100644 --- a/ass1/horner.obj +++ b/ass1/horner.obj @@ -1,4 +1,7 @@ -Hpoly 00000000003D -T0000001E7720256F20319845032020905077201E9840905077201A98409050772016 -T00001E1C984090500F20153F2FFD000001000002000003000004000005000002 -E000000 +Hpoly 000010000043 +T0000101EEF190022779000180000016E10004D984503201D905077201B9840905077 +T00002E1E201798409050772013984090500F20123F2FFD0000020000030000040000 +T00004C0405000002 +M00001505 +M00001C05 +E000014 diff --git a/ass1/test.asm b/ass1/test.asm index c4ee2bf..f7a6891 100644 --- a/ass1/test.asm +++ b/ass1/test.asm @@ -1,4 +1,5 @@ poly START 0 + RSUB LDB x1 END poly diff --git a/ass2/SICocaml/sicxeDune/lib/izvajalnik.ml b/ass2/SICocaml/sicxeDune/lib/izvajalnik.ml index ad88737..bc24ff2 100644 --- a/ass2/SICocaml/sicxeDune/lib/izvajalnik.ml +++ b/ass2/SICocaml/sicxeDune/lib/izvajalnik.ml @@ -74,7 +74,7 @@ let readAddress (state : Processor.state) : int = address (*pridobi effective address in operand*) -let getOperandF3 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int * int= +let getOperandF3 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int * int * int= let ea = if nixbpe.b = 1 && nixbpe.p = 0 then state.regs.b + disp (*B relativno*) else if nixbpe.p = 1 && nixbpe.b = 0 then state.regs.pc + to_signed disp + 3(*PC relativno, ker PC povečamo šele po klicu te funkcije moramo tu +3*) @@ -89,7 +89,13 @@ let getOperandF3 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int else if nixbpe.n = 1 && nixbpe.i = 0 then Processor.readMemAddr state (Processor.readMemAddr state ea) (* indirect *) else failwith "Invalid addressing mode" in - ea ,value + let valueMem = + if nixbpe.n = 1 && nixbpe.i = 1 then ea + else if nixbpe.n = 0 && nixbpe.i = 1 then ea (* immediate value *) + else if nixbpe.n = 1 && nixbpe.i = 0 then Processor.readMemAddr state ea (* indirect *) + else failwith "Invalid addressing mode" + in + ea ,value, valueMem let getOperandF4 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int * int = let ea = @@ -153,7 +159,7 @@ let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) : (*execute Format 3*) let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit = let disp = readDisp state in - let ea ,operand = getOperandF3 state nixbpe disp in + let ea ,operand, valueMem = getOperandF3 state nixbpe disp in (*debugging*) Printf.printf "[Izvajalnik/executeFormat3] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n" (string_of_mnemonic mnemonic) (string_of_nixbpe nixbpe) operand operand; @@ -191,15 +197,15 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode | LDT -> IzvajalnikF3.ldt state operand | LDX -> IzvajalnikF3.ldx state operand | LPS -> notImplemented "LPS4" - | STA -> IzvajalnikF3.sta state ea - | STB -> IzvajalnikF3.stb state ea - | STCH -> IzvajalnikF3.stch state ea + | STA -> IzvajalnikF3.sta state valueMem + | STB -> IzvajalnikF3.stb state valueMem + | STCH -> IzvajalnikF3.stch state valueMem | STF -> notImplemented "STF4" - | STL -> IzvajalnikF3.stl state ea - | STS -> IzvajalnikF3.sts state ea - | STSW -> IzvajalnikF3.stsw state ea - | STT -> IzvajalnikF3.stt state ea - | STX -> IzvajalnikF3.stx state ea + | STL -> IzvajalnikF3.stl state valueMem + | STS -> IzvajalnikF3.sts state valueMem + | STSW -> IzvajalnikF3.stsw state valueMem + | STT -> IzvajalnikF3.stt state valueMem + | STX -> IzvajalnikF3.stx state valueMem (* Control / IO *) | TIX -> IzvajalnikF3.tix state operand diff --git a/ass2/SICocaml/sicxeDune/lib/processor.ml b/ass2/SICocaml/sicxeDune/lib/processor.ml index 085f27d..9147bec 100644 --- a/ass2/SICocaml/sicxeDune/lib/processor.ml +++ b/ass2/SICocaml/sicxeDune/lib/processor.ml @@ -41,7 +41,8 @@ let writeMemAddr (state : state) (address : int) (value : int) : unit = let byte1 = Char.chr ((value lsr 16) land 0xFF) in let byte2 = Char.chr ((value lsr 8) land 0xFF) in let byte3 = Char.chr (value land 0xFF) in - + Printf.printf "[Procesor/writeMemAddr]Napisal byte %02X %02X %02X na %06X\n" + (int_of_char byte1) (int_of_char byte2) (int_of_char byte3) address; (* Write bytes into memory *) Bytes.set state.memory address byte1; Bytes.set state.memory (address+1) byte2; diff --git a/ass3/zbirnik/bin/main.ml b/ass3/zbirnik/bin/main.ml index 2190f97..4b3d6c1 100644 --- a/ass3/zbirnik/bin/main.ml +++ b/ass3/zbirnik/bin/main.ml @@ -2,6 +2,8 @@ open Zbirnik.Parser open Zbirnik.SemanticAnalyzer open Zbirnik.PrehodPrvi open Zbirnik.Simtab +open Zbirnik.DrugiPrehod +open Zbirnik.OpcodeTable (* Helper functions to print optional values *) @@ -27,14 +29,17 @@ let print_lineSemantic_list (lines : lineSemantic list) : unit = ) lines let print_intermediate_file_list (lines : lineSemantic list) : unit = - List.iter (fun l -> - Printf.printf "%s | %8s | %6s | %20s | %s\n" - (print_opt_int l.loc) - (print_opt_string l.label) - (string_of_mnemonic l.opcode) - (string_of_mnemonic_type l.mnem) - (print_opt_string l.comment) - ) lines + List.iter (fun l -> + Printf.printf "%s | %8s | %6s | %20s | x=%d | n = %d | i = %d | %s\n" + (print_opt_int l.loc) + (print_opt_string l.label) + (string_of_mnemonic l.opcode) + (string_of_mnemonic_type l.mnem) + (if l.x then 1 else 0) + (if l.n then 1 else 0) + (if l.i then 1 else 0) + (print_opt_string l.comment) + ) lines let print_symtab (tab : symtab) : unit = Printf.printf "\nSYMBOL TABLE\n"; @@ -46,6 +51,9 @@ let print_symtab (tab : symtab) : unit = ) tab; Printf.printf "----------------------\n" +let print_object_code (objectCodeList : string list) : unit = + List.iter (fun s -> print_endline s) objectCodeList + let run () = let lineSemantic = (checkLineSemanticOfCode (parser "../../ass1/horner.asm") ) in print_lineSemantic_list lineSemantic; @@ -54,6 +62,9 @@ let run () = Printf.printf "Program Length je: %d\n" prlen; print_intermediate_file_list prehod1; print_symtab simtab; + let opcodeTab = get_opcode_table () in + let objectCodeList = drugiPrehod lineSemantic simtab opcodeTab prlen in + print_object_code objectCodeList; () diff --git a/ass3/zbirnik/lib/drugiPrehod.ml b/ass3/zbirnik/lib/drugiPrehod.ml index 0fd04b9..93f1ce3 100644 --- a/ass3/zbirnik/lib/drugiPrehod.ml +++ b/ass3/zbirnik/lib/drugiPrehod.ml @@ -3,8 +3,9 @@ open Simtab open SemanticAnalyzer open Encoder open Instruction +open OpcodeTable -let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : string list = +let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (opcodeTab : opcodeTab) (lenProg : int) : string list = let prviUkaz, ostaliUkazi = match ifl with | [] -> failwith "empty code" @@ -41,29 +42,35 @@ let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : st | [] -> loop xs objectCodeList newStartAddress [] | _ -> loop xs (newTextLine :: objectCodeList) newStartAddress [] end + | BYTE -> + let operand = match x.mnem with | MnemonicSd s -> s | _ -> failwith "narobe mnemType za BYTE" in + let opcode = create_opcode_byte operand in + (*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*) + if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*) + let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*) + loop xs (newTextLine :: objectCodeList) newStartAddress [] + else + loop xs objectCodeList newStartAddress (opcode :: instructionList) + | WORD -> + let operand = match x.mnem with | MnemonicSd s -> s | _ -> failwith "narobe mnemType za WORD" in + let opcode = create_opcode_word operand in + (*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*) + if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*) + let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*) + loop xs (newTextLine :: objectCodeList) newStartAddress [] + else + loop xs objectCodeList newStartAddress (opcode :: instructionList) | _ -> (*if not comment or reserve*) (*if simbol na mestu opeanda*) - let isSymbol, symbol = operand_is_symbol x.mnem in - if isSymbol then - begin - let locSimbola = find_symbol tab symbol in - let opcode = create_opcode_symbol x.opcode locSimbola in - (*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*) - if String.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*) - let newTextLine = instructionList_to_objectCode (List.rev instructionList) newStartAddress in (*naredimo novo T vrstico*) - loop xs (newTextLine :: objectCodeList) newStartAddress [] - else - loop xs objectCodeList newStartAddress (opcode :: instructionList) - end - else - let opcode = create_opcode x.opcode x.mnem in (*symbol je tukaj kar stevilska vrednost/register*) - (*TODO dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*) - begin - if String.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*) - let newTextLine = instructionList_to_objectCode (List.rev instructionList) newStartAddress in (*naredimo novo T vrstico*) - loop xs (newTextLine :: objectCodeList) newStartAddress [] - else - loop xs objectCodeList newStartAddress (opcode :: instructionList) - end + match operand_is_symbol x with + | None -> loop xs objectCodeList newStartAddress instructionList (*None -> ta ukaz se ne zapiše, ga skipamo*) + | Some (_, operand, formatLen) -> + let opcode = create_opcode simtab opcodeTab x.opcode operand formatLen x.loc in + (*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*) + if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*) + let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*) + loop xs (newTextLine :: objectCodeList) newStartAddress [] + else + loop xs objectCodeList newStartAddress (opcode :: instructionList) - in loop ostaliUkazi objectCodeList startAddr instructionList \ No newline at end of file + in loop ostaliUkazi objectCodeList start instructionList \ No newline at end of file diff --git a/ass3/zbirnik/lib/dune b/ass3/zbirnik/lib/dune index 4309626..deeb942 100644 --- a/ass3/zbirnik/lib/dune +++ b/ass3/zbirnik/lib/dune @@ -1,10 +1,3 @@ (library (name zbirnik) - (libraries str) - (modules parser - simtab - semanticAnalyzer - prehodPrvi - encoder - drugiPrehod - instruction)) + (libraries str)) diff --git a/ass3/zbirnik/lib/encoder.ml b/ass3/zbirnik/lib/encoder.ml index cd7eafe..508d7b6 100644 --- a/ass3/zbirnik/lib/encoder.ml +++ b/ass3/zbirnik/lib/encoder.ml @@ -7,17 +7,17 @@ let getZaglavjeAndStart (prviUkaz : lineSemantic) (lenProg : int) : string list | None -> "MOJPROG" (*default ime*) | Some s -> if String.length s > 6 then "MOJPROG" else String.make (6 - String.length s) '0' ^ s (*paddamo z 0 če je < 6*) in - let startAddr = match prviUkaz.mnem with + let startAddrString, startAddrInt = match prviUkaz.mnem with | MnemonicDn s -> (*preverimo ali je pravilne dolzine in naredimo string dolzine 6*) let n = int_of_string s in if n < 0 || n > 0xFFFFFF then invalid_arg "getZaglavje: zacetni naslov out of range" else - Printf.sprintf "%06X" n + (Printf.sprintf "%06X" n), n | _ -> failwith "getZaglavje: invalid mnemonic_type" in let lenObjectCode = Printf.sprintf "%06X" lenProg in - ["H" ^ name ^ startAddr ^ lenObjectCode], int_of_string startAddr (*vrnemo concatiniran string in startAddr*) + ["H" ^ name ^ startAddrString ^ lenObjectCode], startAddrInt(*vrnemo concatiniran string in startAddr*) (*vrne T vrstico*) diff --git a/ass3/zbirnik/lib/instruction.ml b/ass3/zbirnik/lib/instruction.ml index 9b71ffe..7898c17 100644 --- a/ass3/zbirnik/lib/instruction.ml +++ b/ass3/zbirnik/lib/instruction.ml @@ -2,31 +2,143 @@ (*sem spada izbira nacina naslavljanja, dolocanje ali je operand simbol itd..*) open SemanticAnalyzer +open Simtab +open OpcodeTable + +type operand = + | R of register + | RR of register * register + | RN of register * int (*register in število*) + | N of int (*številski operand*) + | S of string (*simbol*) + | None -let string_is_symbol (s : string) : bool * string = +let string_is_symbol (s : string) : bool * operand = try - let _ = int_of_string s in - true, "" - with Failure _ -> false, s + let n = int_of_string s in + false, N n + with Failure _ -> true, S s (*preveri ali je operand iz mnemonic_type simbol ali stevilo*) -let operand_is_symbol (operand : mnemonic_type) : bool * string = (*vrne isSymbol in symbol*) +let operand_is_symbol (x : lineSemantic) : (bool * operand * int) option = (*vrne isSymbol, operand in dolzino ukaza, ali none, če ukaza/direktive ne bomo zapisali v T file*) + match x.mnem with + | MnemonicD -> None + | MnemonicDn s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len) + | MnemonicF1 -> Some (false, None, x.len) + | MnemonicF2n n -> Some (false, N n, x.len) + | MnemonicF2r r1 -> Some (false, R r1, x.len) + | MnemonicF2rn (r1, n) -> Some (false, RN (r1, n), x.len) + | MnemonicF2rr (r1, r2) -> Some (false, RR (r1, r2), x.len) + | MnemonicF3 -> Some (false, None, x.len) + | MnemonicF3m s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len) + | MnemonicF4m s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len) + | MnemonicSd s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len) + | MnemonicSn _ -> None(*RESW in RESB že drugje obdelamo*) + | COMMENT -> None (*Comment ze obdelamo drugje*) + +(*helper funkcija za registre*) +let int_of_reg (reg : register) : int = + match reg with + | A -> 0 + | X -> 1 + | L -> 2 + | B -> 3 + | S -> 4 + | T -> 5 + | F -> 6 + | PC -> 8 + | SW -> 9 + +(*helper funkcija*) +let int_to_hex_width (width : int) (n : int) : string = + let s = Printf.sprintf "%X" n in + let len = String.length s in + if len >= width then s + else String.make (width - len) '0' ^ s + +let char_to_hex c = + Printf.sprintf "%02X" (Char.code c) + +(*naredi binaren zapis F1 oz string nibblov celotnega ukaza*) +let get_bin_instruction_F1 (opcode : int) : string = + int_to_hex_width 2 opcode + +(*naredi binaren zapis F2 oz string nibblov celotnega ukaza*) +let get_bin_instruction_F2 (opcode : int) (operand : operand) : string = match operand with - | MnemonicD -> false, "" - | MnemonicDn s -> string_is_symbol s - | MnemonicF1 -> false, "" - | MnemonicF2n _ -> false, "" - | MnemonicF2r _ -> false, "" - | MnemonicF2rn (_, _) -> false, "" - | MnemonicF2rr (_, _) -> false, "" - | MnemonicF3 -> false, "" - | MnemonicF3m s -> string_is_symbol s - | MnemonicF4m s -> string_is_symbol s - | MnemonicSd s -> string_is_symbol s - | MnemonicSn _ -> false, "" - | COMMENT -> false, "" + | RR (r1, r2) -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 (int_of_reg r2)) + | RN (r1, n) -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 n) + | R r1 -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 0) (*r2 -> 0*) + | N n -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 n) ^ (int_to_hex_width 1 0) + | _ -> failwith "invalid operand type for F2 instruction" +let get_bin_instruction_F3 (opcode : int) (simtab : symtab) (operand : operand) (_ : int option) : string = + match operand with + | None -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 4 0) (*RSUB damo z disp = 0*) + | N n -> (*todo dodaj n_i*) (int_to_hex_width 2 opcode) ^ (*todo add xbpe*) (int_to_hex_width 1 0) ^ (int_to_hex_width 3 n) + | S s -> let operand = Hashtbl.find simtab s in (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 0) ^ (int_to_hex_width 3 operand) + | _ -> "" + +let get_bin_instruction_F4 (opcode : int) (simtab : symtab) (operand : operand) (_ : int option) : string = + match operand with + | None -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 6 0) (*RSUB damo z disp = 0*) + | N n -> (*todo dodaj n_i*) (int_to_hex_width 2 opcode) ^ (*todo add xbpe*) (int_to_hex_width 1 0) ^ (int_to_hex_width 5 n) + | S s -> let operand = Hashtbl.find simtab s in (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 0) ^ (int_to_hex_width 5 operand) + | _ -> "" + +let create_opcode (simtab : symtab) (opcodeTab : opcodeTab) (opcode : mnemonic) (operand : operand) (formatLen : int) (loc : int option) : string = + (*izberi nacin naslavljanja in naredi string ukaza*) + match formatLen with + | 1 -> get_bin_instruction_F1 (find_opcode opcodeTab opcode) + | 2 -> get_bin_instruction_F2 (find_opcode opcodeTab opcode) operand + | 3 -> get_bin_instruction_F3 (find_opcode opcodeTab opcode) simtab operand loc + | 4 -> get_bin_instruction_F4 (find_opcode opcodeTab opcode) simtab operand loc + | _ -> failwith "invalid formatLen" + +(*opcode BYTE direktive*) +let create_opcode_byte (operand : string) : string = + if String.length operand < 3 then + failwith "Invalid BYTE operand, use X'...' or C'...'!" + else + match operand.[0] with + | 'C' -> + (* e.g., C'EOF' *) + let content = String.sub operand 2 (String.length operand - 3) in + let len = String.length content in + if len <> 1 then failwith "BYTE C'...' has to have a operand of length 1 inside hte '...' brackets!" else + String.concat "" (List.init (String.length content) (fun i -> char_to_hex content.[i])) + | 'X' -> + (* e.g., X'F1' *) + let hex = String.sub operand 2 (String.length operand - 3) in + if String.length hex >= 6 then + failwith "WORD X'...' has to have a operand of length <= 6 inside hte '...' brackets!" + else String.make (2 - String.length hex) '0' ^ hex + | _ -> + let n = int_of_string operand in + Printf.sprintf "%02X" n + +let create_opcode_word (operand : string) : string = + if String.length operand = 0 then + failwith "Invalid WORD operand use X'...' or C'...'!" + else + match operand.[0] with + | 'C' -> + (* WORD as C'...' *) + let content = String.sub operand 2 (String.length operand - 3) in + let len = String.length content in + if len <> 3 then failwith "WORD C'...' has to have a operand of length 3 inside hte '...' brackets!" else + let hex = String.concat "" (List.init len (fun i -> char_to_hex content.[i])) in + (* pad to 6 hex digits for WORD *) + if String.length hex >= 6 then hex else String.make (6 - String.length hex) '0' ^ hex + | 'X' -> + (* WORD as X'...' *) + let hex = String.sub operand 2 (String.length operand - 3) in + if String.length hex >= 6 then + failwith "WORD X'...' has to have a operand of length <= 6 inside hte '...' brackets!" + else String.make (6 - String.length hex) '0' ^ hex + | _ -> + (* numeric constant *) + let n = int_of_string operand in + Printf.sprintf "%06X" n -let create_opcode_symbol (opcode : mnemonic) (locSimbola : int) : string = - (*izberi nacin naslavljanja in naredi string ukaza*) \ No newline at end of file diff --git a/ass3/zbirnik/lib/opcodeTable.ml b/ass3/zbirnik/lib/opcodeTable.ml new file mode 100644 index 0000000..6e04fc6 --- /dev/null +++ b/ass3/zbirnik/lib/opcodeTable.ml @@ -0,0 +1,77 @@ +open SemanticAnalyzer + +type opcodeTab = (mnemonic, int) Hashtbl.t + +let find_opcode (tab : opcodeTab) (mnemonic : mnemonic) : int = + try + Hashtbl.find tab mnemonic + with + | Not_found -> failwith (Printf.sprintf "[OpcodeTable] Mnemonic not found: '%s'." (string_of_mnemonic mnemonic) ) + +let get_opcode_table () : opcodeTab= + let opcode_table : (mnemonic, int) Hashtbl.t = Hashtbl.create 128 in + let add mnemonic opcode = + Hashtbl.add opcode_table mnemonic opcode + in + + (* Format 1 *) + add FIX 0xC4; + add FLOAT 0xC0; + add HIO 0xC8; + add NORM 0xC1; + add SIO 0xF0; + add TIO 0xF8; + + (* Format 2 *) + add ADDR 0x90; + add CLEAR 0xB4; + add COMPR 0xA0; + add DIVR 0x9C; + add MULR 0x98; + add RMO 0xAC; + add SHIFTL 0xA4; + add SHIFTR 0xA8; + add SUBR 0x94; + add SVC 0xB0; + add TIXR 0xB8; + + (* Format 3 / 4 *) + add ADD 0x18; + add ADDF 0x58; + add AND 0x40; + add COMP 0x28; + add COMPF 0x88; + add DIV 0x24; + add J 0x3C; + add JEQ 0x30; + add JGT 0x34; + add JLT 0x38; + add JSUB 0x48; + add LDA 0x00; + add LDB 0x68; + add LDCH 0x50; + add LDF 0x70; + add LDL 0x08; + add LDS 0x6C; + add LDT 0x74; + add LDX 0x04; + add LPS 0xD0; + add MUL 0x20; + add OR 0x44; + add RD 0xD8; + add RSUB 0x4C; + add STA 0x0C; + add STB 0x78; + add STCH 0x54; + add STF 0x80; + add STL 0x14; + add STS 0x7C; + add STSW 0xE8; + add STT 0x84; + add STX 0x10; + add SUB 0x1C; + add SUBF 0x5C; + add TD 0xE0; + add TIX 0x2C; + add WD 0xDC; + opcode_table \ No newline at end of file diff --git a/ass3/zbirnik/lib/semanticAnalyzer.ml b/ass3/zbirnik/lib/semanticAnalyzer.ml index 461da51..e84a1dc 100644 --- a/ass3/zbirnik/lib/semanticAnalyzer.ml +++ b/ass3/zbirnik/lib/semanticAnalyzer.ml @@ -117,6 +117,9 @@ type lineSemantic = { ext : bool; (*za razlikovanje med F3 in F4*) opcode : mnemonic; mnem : mnemonic_type; + x : bool; (*ali imamo X naslavljanje*) + n : bool; + i : bool; comment : string option; len : int; (*dolžina, pove za koliko moramo povečati locctr*) mutable loc : int option; (* assigned in pass1 *) @@ -130,78 +133,30 @@ let getMnem (opcode : string) : mnemonic * bool = let o = match opcode with (* ------------------- Format 1 instructions ------------------- *) - | "FIX" -> FIX - | "FLOAT" -> FLOAT - | "HIO" -> HIO - | "NORM" -> NORM - | "SIO" -> SIO - | "TIO" -> TIO + | "FIX" -> FIX | "FLOAT" -> FLOAT | "HIO" -> HIO + | "NORM" -> NORM | "SIO" -> SIO | "TIO" -> TIO (* ------------------- Format 2 instructions ------------------- *) - | "ADDR" -> ADDR - | "CLEAR" -> CLEAR - | "COMPR" -> COMPR - | "DIVR" -> DIVR - | "MULR" -> MULR - | "RMO" -> RMO - | "SHIFTL" -> SHIFTL - | "SHIFTR" -> SHIFTR - | "SUBR" -> SUBR - | "SVC" -> SVC - | "TIXR" -> TIXR + | "ADDR" -> ADDR | "CLEAR" -> CLEAR | "COMPR" -> COMPR | "DIVR" -> DIVR + | "MULR" -> MULR | "RMO" -> RMO | "SHIFTL" -> SHIFTL | "SHIFTR" -> SHIFTR + | "SUBR" -> SUBR | "SVC" -> SVC | "TIXR" -> TIXR (* ------------------- Format 3/4 instructions ------------------- *) - | "ADD" -> ADD - | "ADDF" -> ADDF - | "AND" -> AND - | "COMP" -> COMP - | "COMPF" -> COMPF - | "DIV" -> DIV - | "J" -> J - | "JEQ" -> JEQ - | "JGT" -> JGT - | "JLT" -> JLT - | "JSUB" -> JSUB - | "LDA" -> LDA - | "LDB" -> LDB - | "LDCH" -> LDCH - | "LDF" -> LDF - | "LDL" -> LDL - | "LDS" -> LDS - | "LDT" -> LDT - | "LDX" -> LDX - | "LPS" -> LPS - | "MUL" -> MUL - | "OR" -> OR - | "RD" -> RD - | "RSUB" -> RSUB - | "STA" -> STA - | "STB" -> STB - | "STCH" -> STCH - | "STF" -> STF - | "STL" -> STL - | "STS" -> STS - | "STSW" -> STSW - | "STT" -> STT - | "STX" -> STX - | "SUB" -> SUB - | "SUBF" -> SUBF - | "TD" -> TD - | "TIX" -> TIX - | "WD" -> WD + | "ADD" -> ADD | "ADDF" -> ADDF | "AND" -> AND | "COMP" -> COMP + | "COMPF" -> COMPF | "DIV" -> DIV | "J" -> J | "JEQ" -> JEQ + | "JGT" -> JGT | "JLT" -> JLT | "JSUB" -> JSUB | "LDA" -> LDA + | "LDB" -> LDB | "LDCH" -> LDCH | "LDF" -> LDF | "LDL" -> LDL + | "LDS" -> LDS | "LDT" -> LDT | "LDX" -> LDX | "LPS" -> LPS + | "MUL" -> MUL | "OR" -> OR | "RD" -> RD | "RSUB" -> RSUB | "STA" -> STA + | "STB" -> STB | "STCH" -> STCH | "STF" -> STF | "STL" -> STL | "STS" -> STS + | "STSW" -> STSW | "STT" -> STT | "STX" -> STX | "SUB" -> SUB + | "SUBF" -> SUBF | "TD" -> TD | "TIX" -> TIX | "WD" -> WD (* ------------------- SIC/XE Directives ------------------- *) - | "START" -> START - | "END" -> END - | "ORG" -> ORG - | "EQU" -> EQU - | "BASE" -> BASE - | "NOBASE" -> NOBASE - | "LTORG" -> LTORG - | "RESW" -> RESW - | "RESB" -> RESB - | "WORD" -> WORD - | "BYTE" -> BYTE + | "START" -> START | "END" -> END | "ORG" -> ORG + | "EQU" -> EQU | "BASE" -> BASE | "NOBASE" -> NOBASE + | "LTORG" -> LTORG | "RESW" -> RESW | "RESB" -> RESB + | "WORD" -> WORD | "BYTE" -> BYTE (*comment*) | "COMMENT" -> COMMENT @@ -281,6 +236,7 @@ let getMnemType (opcode : mnemonic) (ext : bool) (operand : string list) : mnemo | _, _ -> failwith (Printf.sprintf "Invalid operands for opcode %s: %d operands" (string_of_mnemonic opcode) (List.length operand)) +(*vrni dolzino ukaza*) let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int = match mnemType with (* ----------- directives with no memory ----------- *) @@ -316,11 +272,48 @@ let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int = | _ -> failwith "Narobe mnemoic glede na mnemType" end +(*preveri ali imaš X naslavljanje*) +let has_index (ops : string list) : bool * string list = (*vrne bool x in operande brez X*) + match ops with + | [lst; x] when String.uppercase_ascii x = "X" -> true, [lst] (*predpostavimo da se X pojavi na drugem mestu in nikoli na tretjem*) + | _ -> false, ops + +(*dobi n in i bita in operande brez # ali @*) +let get_ni_bits (operands : string list) : bool * bool * string list = + match operands with + | [] -> + (true, true, []) + | op :: rest -> + if String.length op = 0 then + (true, true, operands) + else + match op.[0] with + | '#' -> + let stripped =String.sub op 1 (String.length op - 1) in + (false, true, stripped :: rest) + | '@' -> + let stripped = String.sub op 1 (String.length op - 1) in + (true, false, stripped :: rest) + | _ -> + (true, true, operands) + let checkLineSemantic (line : line) : lineSemantic = let mnem, ext = getMnem line.opcode in - let mnemType = getMnemType mnem ext line.operand in + let x, ops = has_index line.operand in + let n, i, ops = get_ni_bits ops in + let mnemType = getMnemType mnem ext ops in let dolzina = getLen mnemType mnem in - {line_no = line.line_no; label = line.label; ext = ext; opcode = mnem; mnem = mnemType; comment = line.comment; len = dolzina; loc = line.loc} + { line_no = line.line_no; + label = line.label; + ext = ext; + opcode = mnem; + mnem = mnemType; + x = x; + n = n; + i = i; + comment = line.comment; + len = dolzina; + loc = line.loc} let checkLineSemanticOfCode (code : line list) : lineSemantic list = List.map (checkLineSemantic) code diff --git a/ass3/zbirnik/lib/simtab.ml b/ass3/zbirnik/lib/simtab.ml index 5658f7e..1fe1fec 100644 --- a/ass3/zbirnik/lib/simtab.ml +++ b/ass3/zbirnik/lib/simtab.ml @@ -11,5 +11,8 @@ let add_symbol (tab : symtab) (label : string) (addr : int) = else Hashtbl.add tab label addr -let find_symbol (tab : symtab) (label : string) : int = - Hashtbl.find tab label \ No newline at end of file + let find_symbol (tab : symtab) (label : string) : int = + try + Hashtbl.find tab label + with + | Not_found -> failwith (Printf.sprintf "[SimTab] Symbol not found: '%s'." label) \ No newline at end of file