Implemented addition

This commit is contained in:
Eduard Urbach 2024-06-24 14:14:07 +02:00
parent 41f5dcbe62
commit 597cb9abed
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
6 changed files with 78 additions and 23 deletions

View File

@ -5,8 +5,11 @@ main() {
hello() { hello() {
write := 1 write := 1
stdout := 1 stdout := 1
address := 4194305 address := 4194304
length := 3 length := 0
address += 1
length += 3
loop { loop {
syscall(write, stdout, address, length) syscall(write, stdout, address, length)

View File

@ -113,6 +113,16 @@ func (f *Function) CompileInstruction(line token.List) error {
return f.CompileFunctionCall(expr) return f.CompileFunctionCall(expr)
} }
if expr.Token.Kind == token.Operator {
switch expr.Token.Text() {
case "+=":
name := expr.Children[0].Token.Text()
number, _ := strconv.Atoi(expr.Children[1].Token.Text())
f.Assembler.AddRegisterNumber(f.Variables[name].Register, uint64(number))
return nil
}
}
return errors.New(&errors.InvalidInstruction{Instruction: expr.Token.Text()}, f.File, expr.Token.Position) return errors.New(&errors.InvalidInstruction{Instruction: expr.Token.Text()}, f.File, expr.Token.Position)
} }

18
src/build/arch/x64/Add.go Normal file
View File

@ -0,0 +1,18 @@
package x64
import "git.akyoto.dev/cli/q/src/build/cpu"
// AddRegNum8 adds a byte to the given register.
func AddRegNum8(code []byte, destination cpu.Register, number uint8) []byte {
if destination >= 8 {
code = append(code, REX(0, 0, 0, 1))
destination -= 8
}
return append(
code,
0x83,
ModRM(0b11, 0b000, byte(destination)),
byte(number),
)
}

View File

@ -27,21 +27,15 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
for _, x := range a.Instructions { for _, x := range a.Instructions {
switch x.Mnemonic { switch x.Mnemonic {
case MOVE: case ADD:
switch operands := x.Data.(type) { switch operands := x.Data.(type) {
case *RegisterNumber: case *RegisterNumber:
code = x64.MoveRegNum32(code, operands.Register, uint32(operands.Number)) code = x64.AddRegNum8(code, operands.Register, uint8(operands.Number))
case *RegisterRegister: case *RegisterRegister:
code = x64.MoveRegReg64(code, operands.Destination, operands.Source) // code = x64.AddRegReg64(code, operands.Destination, operands.Source)
} }
case RETURN:
code = x64.Return(code)
case SYSCALL:
code = x64.Syscall(code)
case CALL: case CALL:
code = x64.Call(code, 0x00_00_00_00) code = x64.Call(code, 0x00_00_00_00)
size := 4 size := 4
@ -77,6 +71,21 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
case LABEL: case LABEL:
labels[x.Data.(*Label).Name] = Address(len(code)) labels[x.Data.(*Label).Name] = Address(len(code))
case MOVE:
switch operands := x.Data.(type) {
case *RegisterNumber:
code = x64.MoveRegNum32(code, operands.Register, uint32(operands.Number))
case *RegisterRegister:
code = x64.MoveRegReg64(code, operands.Destination, operands.Source)
}
case RETURN:
code = x64.Return(code)
case SYSCALL:
code = x64.Syscall(code)
default: default:
panic("Unknown mnemonic: " + x.Mnemonic.String()) panic("Unknown mnemonic: " + x.Mnemonic.String())
} }

View File

@ -2,6 +2,17 @@ package asm
import "git.akyoto.dev/cli/q/src/build/cpu" import "git.akyoto.dev/cli/q/src/build/cpu"
// AddRegisterNumber adds a number to the given register.
func (a *Assembler) AddRegisterNumber(reg cpu.Register, number uint64) {
a.Instructions = append(a.Instructions, Instruction{
Mnemonic: ADD,
Data: &RegisterNumber{
Register: reg,
Number: number,
},
})
}
// MoveRegisterNumber moves a number into the given register. // MoveRegisterNumber moves a number into the given register.
func (a *Assembler) MoveRegisterNumber(reg cpu.Register, number uint64) { func (a *Assembler) MoveRegisterNumber(reg cpu.Register, number uint64) {
a.Instructions = append(a.Instructions, Instruction{ a.Instructions = append(a.Instructions, Instruction{

View File

@ -4,17 +4,30 @@ type Mnemonic uint8
const ( const (
NONE Mnemonic = iota NONE Mnemonic = iota
ADD
CALL
JUMP
LABEL
MOVE MOVE
RETURN RETURN
SYSCALL SYSCALL
LABEL
CALL
JUMP
) )
// String returns a human readable version. // String returns a human readable version.
func (m Mnemonic) String() string { func (m Mnemonic) String() string {
switch m { switch m {
case ADD:
return "add"
case CALL:
return "call"
case JUMP:
return "jump"
case LABEL:
return "label"
case MOVE: case MOVE:
return "move" return "move"
@ -23,15 +36,6 @@ func (m Mnemonic) String() string {
case SYSCALL: case SYSCALL:
return "syscall" return "syscall"
case LABEL:
return "label"
case CALL:
return "call"
case JUMP:
return "jump"
} }
return "NONE" return "NONE"