From 843806d7c80bfec8fcea5fae81961fa35c91a804 Mon Sep 17 00:00:00 2001 From: Jacob McDonnell Date: Wed, 29 May 2024 14:19:43 -0400 Subject: ELF Implementation --- assemble.go | 48 ++++++++++++++++++++++++++++++++++--- qdma.go | 2 +- symbol.go | 8 +++++++ test6.asm | 24 ------------------- test6.bin | Bin 246 -> 0 bytes tests/fibtest.asm | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/fibtest.bin | Bin 0 -> 364 bytes tests/test5.bin | Bin 56 -> 140 bytes tests/test6.asm | 24 +++++++++++++++++++ tests/test6.bin | Bin 0 -> 246 bytes tests/test7.asm | 43 +++++++++++++++++++++++++++++++++ tests/test7.bin | Bin 0 -> 306 bytes 12 files changed, 191 insertions(+), 28 deletions(-) delete mode 100755 test6.asm delete mode 100755 test6.bin create mode 100755 tests/fibtest.asm create mode 100755 tests/fibtest.bin create mode 100755 tests/test6.asm create mode 100755 tests/test6.bin create mode 100755 tests/test7.asm create mode 100755 tests/test7.bin diff --git a/assemble.go b/assemble.go index e3bb2e5..923fb33 100755 --- a/assemble.go +++ b/assemble.go @@ -36,6 +36,7 @@ var Instructions = map[string]struct { "srl": {true, 2}, "lw": {false, 35}, "sw": {false, 43}, + "lui": {false, 15}, "slt": {true, 42}, "slti": {false, 10}, "sltiu": {false, 11}, @@ -106,8 +107,14 @@ func Encode(inst []string, pc int32) ([]byte, error) { 16) | (RegNums[inst[1]] << 11) | function.opcode } else if function.opcode == 2 || function.opcode == 3 { label, _ := labels[inst[1]] - addr := label.pos + SectionPos[label.section] + addr := label.pos + SectionStart[label.section] ret = (function.opcode << 26) | uint32(addr&0x03FFFFFF) + } else if function.opcode == 15 { + imm, err := strconv.Atoi(inst[2]) + if err != nil { + return nil, err + } + ret = (function.opcode << 26) | (RegNums[inst[1]] << 16) | uint32(imm) } else if function.opcode == 35 || function.opcode == 43 { immReg, err := regexp.Compile("^[0-9]+") if err != nil { @@ -125,11 +132,40 @@ func Encode(inst []string, pc int32) ([]byte, error) { reg := regReg.FindString(inst[2]) ret = (function.opcode << 26) | (RegNums[reg] << 21) | (RegNums[inst[1]] << 16) | (0xFFFF & uint32(imm)) + } else if inst[0] == "la" { + bytes64 := make([]byte, 8) + label, isLabel := labels[inst[2]] + addr := int32(label.pos + SectionStart[label.section]) + if !isLabel { + err := fmt.Errorf("Unknown label: %s\n", inst[2]) + return nil, err + } + lui, err := Parse(fmt.Sprintf("lui %s, %d", inst[1], (addr >> 8))) + if err != nil { + return nil, err + } + ori, err := Parse(fmt.Sprintf("ori %s, %s, %d", inst[1], inst[1], + addr&0xFFFF)) + if err != nil { + return nil, err + } + b1, err := Encode(lui, pc) + if err != nil { + return nil, err + } + b2, err := Encode(ori, pc) + if err != nil { + return nil, err + } + copy(bytes64[:4], b1) + copy(bytes64[4:], b2) + return bytes64, nil } else { label, isLabel := labels[inst[3]] - addr := int32(label.pos + SectionPos[label.section]) + addr := int32(label.pos + SectionStart[label.section]) if isLabel { - imm = int16(addr - pc - 12) + imm = int16(addr - pc - 8) + fmt.Println(inst[3], label.pos, SectionStart[label.section], imm, pc) } else { i, err := strconv.Atoi(inst[3]) if err != nil { @@ -140,6 +176,7 @@ func Encode(inst []string, pc int32) ([]byte, error) { ret = (function.opcode << 26) | (RegNums[inst[2]] << 21) | (RegNums[inst[1]] << 16) | (0xFFFF & uint32(imm)) } + fmt.Println(inst) binary.NativeEndian.PutUint32(bytes, ret) return bytes, nil } @@ -159,6 +196,7 @@ func Assemble(path string, out *os.File) { continue } else if s == ".data" || s == ".rodata" || s == ".bss" { isText = false + i -= 4 continue } else if s == ".text" { isText = true @@ -166,6 +204,7 @@ func Assemble(path string, out *os.File) { } if !isText { + i -= 4 continue } @@ -192,6 +231,9 @@ func Assemble(path string, out *os.File) { if _, err = out.Write(bytes); err != nil { panic(err) } + if len(bytes) == 8 { + i += 4 + } } if err := scanner.Err(); err != nil { diff --git a/qdma.go b/qdma.go index 5a7a7a4..3b08aba 100755 --- a/qdma.go +++ b/qdma.go @@ -66,7 +66,7 @@ func main() { var fOffset, mOffset uint32 = 0, 0 for j, p := range PHeaders[:i] { - PHeaders[j].offset = uint32(i*PHENSIZE) + fOffset + PHeaders[j].offset = uint32(i*PHENSIZE) + fOffset + EHSIZE fOffset += p.filesz PHeaders[j].vaddr = mOffset mOffset += p.memsz diff --git a/symbol.go b/symbol.go index 5a71473..98c5f07 100755 --- a/symbol.go +++ b/symbol.go @@ -18,6 +18,7 @@ type PosPair struct { var labels map[string]PosPair = make(map[string]PosPair) var SectionPos [4]uint +var SectionStart [4]uint const ( TEXT = 0 @@ -82,8 +83,15 @@ func LabelFind(path string, dTemp, rTemp *os.File) { if err != nil { panic(err) } + if Section == TEXT && s[0] == "la" { + offset += 4 + } *i += offset } + SectionStart[0] = 0 + SectionStart[1] = SectionPos[0] + SectionStart[2] = SectionPos[1] + SectionPos[1] + SectionStart[3] = SectionPos[2] + SectionPos[2] } func CalcOffset(s []string, Section uint8, dTemp, rTemp *os.File) (uint, error) { diff --git a/test6.asm b/test6.asm deleted file mode 100755 index 3c9ab62..0000000 --- a/test6.asm +++ /dev/null @@ -1,24 +0,0 @@ -.text - -addi $t0, $zero, x -addi $v0, $zero, 1 -lw $a0, 0($t0) -syscall -addi $v0, $zero, 10 -syscall - -.data - -x: .word 0xFFFFFFFF -cats: .asciiz "cats are cool\n" -c: .byte 0 - -.rodata - -g: .word 50 -dogs: .ascii "Dogs are cool\n" -h: .half 255 - -.bss -fib: .space 40 - diff --git a/test6.bin b/test6.bin deleted file mode 100755 index e81d82c..0000000 Binary files a/test6.bin and /dev/null differ diff --git a/tests/fibtest.asm b/tests/fibtest.asm new file mode 100755 index 0000000..bd053b9 --- /dev/null +++ b/tests/fibtest.asm @@ -0,0 +1,70 @@ +.data + +str: + .asciiz "Fibinacci Number " + +str2: + .asciiz " is: " + +fib: + .space 40 + +.text + +main: + addi $t0, $zero, 0 + addi $t1, $zero, 1 + add $t3, $zero, $zero + la $t6, fib + addi $t5, $zero, 9 + + loop: + add $t2, $t1, $t0 + add $t1, $zero, $t0 + add $t0, $zero, $t2 + sw $t2, 00($t6) + addi $t3, $t3, 1 + addi $t6, $t6, 4 + bne $t3, $t5, loop + nop + addi $t6, $t6, -4 + loop2: + la $a0, str + jal PrintStr + nop + + add $a0, $zero, $t3 + jal PrintInt + nop + + la $a0, str2 + jal PrintStr + nop + + lw $a0, 00($t6) + jal PrintInt + nop + + addi $a0, $zero, 10 + addi $v0, $zero, 11 + syscall + + addi $t3, $t3, -1 + addi $t6, $t6, -4 + bne $t3, $zero, loop2 + nop + + addi $v0, $zero, 10 + syscall + +PrintInt: + addi $v0, $zero, 1 + syscall + jr $ra + nop + +PrintStr: + addi $v0, $zero, 4 + syscall + jr $ra + nop \ No newline at end of file diff --git a/tests/fibtest.bin b/tests/fibtest.bin new file mode 100755 index 0000000..167f491 Binary files /dev/null and b/tests/fibtest.bin differ diff --git a/tests/test5.bin b/tests/test5.bin index dd1cc83..78175de 100755 Binary files a/tests/test5.bin and b/tests/test5.bin differ diff --git a/tests/test6.asm b/tests/test6.asm new file mode 100755 index 0000000..3c9ab62 --- /dev/null +++ b/tests/test6.asm @@ -0,0 +1,24 @@ +.text + +addi $t0, $zero, x +addi $v0, $zero, 1 +lw $a0, 0($t0) +syscall +addi $v0, $zero, 10 +syscall + +.data + +x: .word 0xFFFFFFFF +cats: .asciiz "cats are cool\n" +c: .byte 0 + +.rodata + +g: .word 50 +dogs: .ascii "Dogs are cool\n" +h: .half 255 + +.bss +fib: .space 40 + diff --git a/tests/test6.bin b/tests/test6.bin new file mode 100755 index 0000000..f9ed3d3 Binary files /dev/null and b/tests/test6.bin differ diff --git a/tests/test7.asm b/tests/test7.asm new file mode 100755 index 0000000..158bf75 --- /dev/null +++ b/tests/test7.asm @@ -0,0 +1,43 @@ +.text + +la $t0, x +lw $a0, 0($t0) +jal PrintInt +nop +la $a0, cats +jal PrintStr +nop +j exit +nop + +PrintInt: + addi $v0, $zero, 1 + syscall + jr $ra + nop + +PrintStr: + addi $v0, $zero, 4 + syscall + jr $ra + nop + +exit: + addi $v0, $zero, 10 + syscall + +.data + +x: .word 0xFFFFFFFF +cats: .asciiz "cats are cool\n" +c: .byte 0 + +.rodata + +g: .word 50 +dogs: .ascii "Dogs are cool\n" +h: .half 255 + +.bss +fib: .space 40 + diff --git a/tests/test7.bin b/tests/test7.bin new file mode 100755 index 0000000..daadfee Binary files /dev/null and b/tests/test7.bin differ -- cgit v1.2.3