From c41d9302ae9d62a2a18afc26758085d9633ab314 Mon Sep 17 00:00:00 2001 From: Jacob McDonnell Date: Mon, 13 May 2024 13:14:11 -0400 Subject: Ignoring Comments and Encoding Jumps --- README.md | 10 ++++++++ qdma | Bin 2356276 -> 2356292 bytes qdma.go | 74 ++++++++++++++++++++++++++++++++++++++------------------ tests/test3.asm | 0 tests/test3.bin | 0 tests/test4.asm | 12 +++++---- tests/test4.bin | Bin 56 -> 56 bytes 7 files changed, 67 insertions(+), 29 deletions(-) mode change 100644 => 100755 tests/test3.asm mode change 100644 => 100755 tests/test3.bin mode change 100644 => 100755 tests/test4.bin diff --git a/README.md b/README.md index fc47712..453c4bd 100755 --- a/README.md +++ b/README.md @@ -8,6 +8,16 @@ emulator. Currently this assembler can only handle standard instructions, which means no sections and no predefined data outside of an I-Type instruction. +## TODO + +- ~Assemble Instructions into Binary~ + +- ~Handle Labels and Jumps~ + +- Encode Data Section into Binary + +- ~Ignore Comments~ + ## Instructions Here is a list of supported instructions. diff --git a/qdma b/qdma index 59ac282..c89f7ae 100755 Binary files a/qdma and b/qdma differ diff --git a/qdma.go b/qdma.go index 6b2de1d..6ff9e81 100755 --- a/qdma.go +++ b/qdma.go @@ -103,24 +103,27 @@ func LabelFind(path string) { panic(err) } + if len(s) == 1 && s[0] == "" { + i -= 4 + continue + } + if strings.Contains(s[0], ":") { labels[strings.ReplaceAll(s[0], ":", "")] = uint(i) } } } -func Encode(instruction string, pc int32) uint32 { +func Encode(inst []string, pc int32) (uint32, error) { var ret uint32 = 0 offset := 0 - if instruction == "syscall" { - return 12 - } else if instruction == "nop" { - return 0 - } - - inst, err := Parse(instruction) - if err != nil { - panic(err) + for _, s := range inst { + switch s { + case "syscall": + return 12, nil + case "nop": + return 0, nil + } } _, isLabel := labels[strings.ReplaceAll(inst[0], ":", "")] @@ -128,30 +131,31 @@ func Encode(instruction string, pc int32) uint32 { offset += 1 } - fmt.Println(inst) - if Instructions[inst[0+offset]].isRtype { + function := Instructions[inst[offset]] + if function.isRtype && function.opcode == 8 { + ret = (RegNums[inst[1+offset]] << 21) | function.opcode + } else if function.isRtype { ret = (RegNums[inst[2+offset]] << 21) | (RegNums[inst[3+offset]] << - 16) | (RegNums[inst[1+offset]] << 11) | - Instructions[inst[0+offset]].opcode + 16) | (RegNums[inst[1+offset]] << 11) | function.opcode + } else if function.opcode == 2 || function.opcode == 3 { + label, _ := labels[inst[1+offset]] + ret = (function.opcode << 26) | uint32(label&0x03FFFFFF) } else { 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) + return 0, err } imm = int16(i) } - ret = (Instructions[inst[0+offset]].opcode << 26) | - (RegNums[inst[2+offset]] << 21) | (RegNums[inst[1+offset]] << 16) | - (0x0000FFFF & uint32(imm)) + ret = (function.opcode << 26) | (RegNums[inst[2+offset]] << 21) | + (RegNums[inst[1+offset]] << 16) | (0x0000FFFF & uint32(imm)) } - return ret + return ret, nil } func Assemble(path string) { @@ -168,15 +172,31 @@ func Assemble(path string) { defer out.Close() scanner := bufio.NewScanner(file) + bs := make([]byte, 4) for i := 0; scanner.Scan(); i += 4 { var s string = scanner.Text() if s == "" { i -= 4 continue } - bs := make([]byte, 4) - binary.BigEndian.PutUint32(bs, Encode(s, int32(i))) - _, err := out.Write(bs) + + inst, err := Parse(s) + if err != nil { + panic(err) + } + + if len(inst) == 1 && inst[0] == "" { + i -= 4 + continue + } + + bytes, err := Encode(inst, int32(i)) + if err != nil { + fmt.Fprintf(os.Stderr, "while encoding %s: %v", s, err) + panic(err) + } + binary.BigEndian.PutUint32(bs, bytes) + _, err = out.Write(bs) if err != nil { panic(err) } @@ -194,6 +214,11 @@ func Parse(s string) ([]string, error) { panic(err) }*/ + comments, err := regexp.Compile("#.*") + if err != nil { + panic(err) + } + edgeWs, err := regexp.Compile("(^\\s+|\\s+$)+") if err != nil { return nil, err @@ -209,6 +234,7 @@ func Parse(s string) ([]string, error) { return nil, err } + s = comments.ReplaceAllString(s, "") s = edgeWs.ReplaceAllString(s, "") s = whiteSpace.ReplaceAllString(s, ",") s = repeatComma.ReplaceAllString(s, ",") diff --git a/tests/test3.asm b/tests/test3.asm old mode 100644 new mode 100755 diff --git a/tests/test3.bin b/tests/test3.bin old mode 100644 new mode 100755 diff --git a/tests/test4.asm b/tests/test4.asm index af5dcc4..e116ac7 100755 --- a/tests/test4.asm +++ b/tests/test4.asm @@ -1,15 +1,17 @@ -addi $t0, $zero, 10 -addi $t1, $zero, 12 +# This is a test program to test the capabilities of the assembler + +addi $t0, $zero, 10 # load 10 into $t0 +addi $t1, $zero, 12 # load 12 into $t1 add $t2, $t1, $t0 -beq $zero, $zero, PrintInt +jal PrintInt nop -caller: beq $zero, $zero, Exit +j Exit # Exit the program nop PrintInt: add $a0, $t2, $zero addi $v0, $zero, 1 syscall -beq $zero, $zero, caller +jr $ra nop Exit: addi $v0, $zero, 10 diff --git a/tests/test4.bin b/tests/test4.bin old mode 100644 new mode 100755 index 1c6e0bd..61cb805 Binary files a/tests/test4.bin and b/tests/test4.bin differ -- cgit v1.2.3