working on ass3, todo pc, nixbpe
This commit is contained in:
parent
6261d9fe37
commit
beabcde7db
15 changed files with 412 additions and 194 deletions
|
|
@ -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
|
||||
|
|
@ -36,3 +38,5 @@ x WORD 2
|
|||
|
||||
.rezultat
|
||||
rez RESW 1
|
||||
|
||||
END start
|
||||
|
|
@ -1,21 +1,24 @@
|
|||
***** Section <default> *****
|
||||
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
|
||||
<default> 00000 0003D 16 8 1
|
||||
<default> 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
Hpoly 00000000003D
|
||||
T0000001E7720256F20319845032020905077201E9840905077201A98409050772016
|
||||
T00001E1C984090500F20153F2FFD000001000002000003000004000005000002
|
||||
E000000
|
||||
Hpoly 000010000043
|
||||
T0000101EEF190022779000180000016E10004D984503201D905077201B9840905077
|
||||
T00002E1E201798409050772013984090500F20123F2FFD0000020000030000040000
|
||||
T00004C0405000002
|
||||
M00001505
|
||||
M00001C05
|
||||
E000014
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
poly START 0
|
||||
RSUB
|
||||
LDB x1
|
||||
END poly
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
in loop ostaliUkazi objectCodeList start instructionList
|
||||
|
|
@ -1,10 +1,3 @@
|
|||
(library
|
||||
(name zbirnik)
|
||||
(libraries str)
|
||||
(modules parser
|
||||
simtab
|
||||
semanticAnalyzer
|
||||
prehodPrvi
|
||||
encoder
|
||||
drugiPrehod
|
||||
instruction))
|
||||
(libraries str))
|
||||
|
|
|
|||
|
|
@ -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*)
|
||||
|
|
|
|||
|
|
@ -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 create_opcode_symbol (opcode : mnemonic) (locSimbola : int) : string =
|
||||
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
|
||||
|
||||
|
|
|
|||
77
ass3/zbirnik/lib/opcodeTable.ml
Normal file
77
ass3/zbirnik/lib/opcodeTable.ml
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue