summaryrefslogtreecommitdiff
path: root/assemble.go
diff options
context:
space:
mode:
Diffstat (limited to 'assemble.go')
-rwxr-xr-xassemble.go48
1 files changed, 45 insertions, 3 deletions
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 {