summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xqdmabin2427020 -> 2356276 bytes
-rwxr-xr-xqdma.go96
-rwxr-xr-xtests/test2.asm4
-rw-r--r--tests/test3.asm3
-rwxr-xr-xtests/test4.asm16
-rw-r--r--tests/test4.binbin0 -> 56 bytes
6 files changed, 94 insertions, 25 deletions
diff --git a/qdma b/qdma
index 29ddd33..59ac282 100755
--- a/qdma
+++ b/qdma
Binary files 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
--- /dev/null
+++ b/tests/test4.bin
Binary files differ