diff options
Diffstat (limited to 'assemble.go')
| -rwxr-xr-x | assemble.go | 48 |
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 { |
