From f7b17ef5b489d7bdeeda7e7f4b073727b0de29f9 Mon Sep 17 00:00:00 2001 From: Jacob McDonnell Date: Fri, 10 May 2024 18:13:49 -0400 Subject: Initial Implementation of Labels --- qdma | Bin 2427020 -> 2356276 bytes qdma.go | 96 +++++++++++++++++++++++++++++++++++++++++++------------- tests/test2.asm | 4 +-- tests/test3.asm | 3 +- tests/test4.asm | 16 ++++++++++ tests/test4.bin | Bin 0 -> 56 bytes 6 files changed, 94 insertions(+), 25 deletions(-) create mode 100755 tests/test4.asm create mode 100644 tests/test4.bin diff --git a/qdma b/qdma index 29ddd33..59ac282 100755 Binary files a/qdma and b/qdma differ diff --git a/qdma.go b/qdma.go index a968397..6b2de1d 100755 --- a/qdma.go +++ b/qdma.go @@ -3,6 +3,7 @@ package main import ( "bufio" "encoding/binary" + "fmt" "os" "regexp" "strconv" @@ -80,27 +81,75 @@ var RegNums = map[string]uint32{ "$ra": 31, } -func Encode(instruction string) uint32 { +// Map for labels and their addresses +var labels map[string]uint = make(map[string]uint) + +func LabelFind(path string) { + file, err := os.Open(path) + if err != nil { + panic(err) + } + defer file.Close() + + input := bufio.NewScanner(file) + + for i := 0; input.Scan(); i += 4 { + if input.Text() == "" { + i -= 4 + continue + } + s, err := Parse(input.Text()) + if err != nil { + panic(err) + } + + if strings.Contains(s[0], ":") { + labels[strings.ReplaceAll(s[0], ":", "")] = uint(i) + } + } +} + +func Encode(instruction string, pc int32) uint32 { var ret uint32 = 0 + offset := 0 if instruction == "syscall" { return 12 + } else if instruction == "nop" { + return 0 } - inst, err := parse(instruction) + + inst, err := Parse(instruction) if err != nil { panic(err) } - if Instructions[inst[0]].isRtype { - ret = (RegNums[inst[2]] << 21) | (RegNums[inst[3]] << 16) | - (RegNums[inst[1]] << 11) | Instructions[inst[0]].opcode + + _, isLabel := labels[strings.ReplaceAll(inst[0], ":", "")] + if isLabel { + offset += 1 + } + + fmt.Println(inst) + if Instructions[inst[0+offset]].isRtype { + ret = (RegNums[inst[2+offset]] << 21) | (RegNums[inst[3+offset]] << + 16) | (RegNums[inst[1+offset]] << 11) | + Instructions[inst[0+offset]].opcode } else { - var imm int32 - i, err := strconv.Atoi(inst[3]) - if err != nil { - panic(err) + var imm int16 + addr, isLabel := labels[inst[3+offset]] + if isLabel { + imm = int16(int32(addr) - pc - 12) + fmt.Println(imm, int32(addr) - pc - 12, uint32(imm) & 0x0000FFFF) + } else { + i, err := strconv.Atoi(inst[3+offset]) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", instruction) + panic(err) + } + imm = int16(i) } - imm = int32(i) - ret = (Instructions[inst[0]].opcode << 26) | (RegNums[inst[2]] << 21) | - (RegNums[inst[1]] << 16) | uint32(imm) + ret = (Instructions[inst[0+offset]].opcode << 26) | + (RegNums[inst[2+offset]] << 21) | (RegNums[inst[1+offset]] << 16) | + (0x0000FFFF & uint32(imm)) } return ret } @@ -119,15 +168,17 @@ func Assemble(path string) { defer out.Close() scanner := bufio.NewScanner(file) - for scanner.Scan() { + for i := 0; scanner.Scan(); i += 4 { var s string = scanner.Text() - if s != "" { - bs := make([]byte, 4) - binary.BigEndian.PutUint32(bs, Encode(s)) - _, err := out.Write(bs) - if err != nil { - panic(err) - } + if s == "" { + i -= 4 + continue + } + bs := make([]byte, 4) + binary.BigEndian.PutUint32(bs, Encode(s, int32(i))) + _, err := out.Write(bs) + if err != nil { + panic(err) } } @@ -136,7 +187,7 @@ func Assemble(path string) { } } -func parse(s string) ([]string, error) { +func Parse(s string) ([]string, error) { /* regex to match 00($t0) offset, err := regexp.Compile("[0-9]+\\((.*)+\\)") if err != nil { @@ -166,6 +217,7 @@ func parse(s string) ([]string, error) { func main() { for _, arg := range os.Args[1:] { - Assemble(arg) + LabelFind(arg) // First pass to find all labels. + Assemble(arg) // Second pass to assemble the instructions. } } diff --git a/tests/test2.asm b/tests/test2.asm index e22cd5e..4e794d7 100755 --- a/tests/test2.asm +++ b/tests/test2.asm @@ -1,6 +1,6 @@ .data -fib: space 40 +fib: .space 40 str: .asciiz "Hello" @@ -8,7 +8,7 @@ str: .asciiz "Hello" main: addi $t0, $zero, 10 addi $t1, $zero, 11 loop: add $t2, $t1, $t0 - + addi $v0, $zero, 1 addi $a0, $t2, 0 syscall diff --git a/tests/test3.asm b/tests/test3.asm index cf5b1a8..e6ab8a6 100644 --- a/tests/test3.asm +++ b/tests/test3.asm @@ -1,6 +1,7 @@ -addiu $sp,$sp,-40 +main: addiu $sp,$sp,-40 sw $31,36($sp) sw $fp,32($sp) sw $16,28($sp) move $fp,$sp sw $4,40($fp) +j main diff --git a/tests/test4.asm b/tests/test4.asm new file mode 100755 index 0000000..af5dcc4 --- /dev/null +++ b/tests/test4.asm @@ -0,0 +1,16 @@ +addi $t0, $zero, 10 +addi $t1, $zero, 12 +add $t2, $t1, $t0 +beq $zero, $zero, PrintInt +nop +caller: beq $zero, $zero, Exit +nop + +PrintInt: add $a0, $t2, $zero +addi $v0, $zero, 1 +syscall +beq $zero, $zero, caller +nop + +Exit: addi $v0, $zero, 10 +syscall diff --git a/tests/test4.bin b/tests/test4.bin new file mode 100644 index 0000000..1c6e0bd Binary files /dev/null and b/tests/test4.bin differ -- cgit v1.2.3