Implemented subtraction

This commit is contained in:
Eduard Urbach 2024-06-24 16:55:15 +02:00
parent 597cb9abed
commit b018d8de61
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
9 changed files with 92 additions and 28 deletions

View File

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

View File

@ -118,7 +118,13 @@ func (f *Function) CompileInstruction(line token.List) error {
case "+=": case "+=":
name := expr.Children[0].Token.Text() name := expr.Children[0].Token.Text()
number, _ := strconv.Atoi(expr.Children[1].Token.Text()) number, _ := strconv.Atoi(expr.Children[1].Token.Text())
f.Assembler.AddRegisterNumber(f.Variables[name].Register, uint64(number)) f.Assembler.AddRegisterNumber(f.Variables[name].Register, number)
return nil
case "-=":
name := expr.Children[0].Token.Text()
number, _ := strconv.Atoi(expr.Children[1].Token.Text())
f.Assembler.SubRegisterNumber(f.Variables[name].Register, number)
return nil return nil
} }
} }
@ -158,7 +164,7 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
return err return err
} }
f.Assembler.MoveRegisterNumber(register, uint64(n)) f.Assembler.MoveRegisterNumber(register, n)
return nil return nil
case token.String: case token.String:

View File

@ -1,18 +0,0 @@
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

@ -0,0 +1,15 @@
package x64
import (
"git.akyoto.dev/cli/q/src/build/cpu"
)
// AddRegNum adds a number to the given register.
func AddRegNum(code []byte, destination cpu.Register, number int) []byte {
return numberToRegister(0x83, 0x81, 0b000, code, destination, number)
}
// SubRegNum subtracts a number from the given register.
func SubRegNum(code []byte, destination cpu.Register, number int) []byte {
return numberToRegister(0x83, 0x81, 0b101, code, destination, number)
}

View File

@ -0,0 +1,41 @@
package x64
import (
"math"
"git.akyoto.dev/cli/q/src/build/cpu"
)
// numberToRegister encodes an instruction with a register and a number parameter.
func numberToRegister(opCode8 byte, opCode32 byte, reg byte, code []byte, destination cpu.Register, number int) []byte {
b := byte(0)
if destination >= 8 {
b = 1
destination -= 8
}
rex := REX(1, 0, 0, b)
modRM := ModRM(0b11, reg, byte(destination))
if number >= math.MinInt8 && number <= math.MaxInt8 {
return append(
code,
rex,
opCode8,
modRM,
byte(number),
)
}
return append(
code,
rex,
opCode32,
modRM,
byte(number),
byte(number>>8),
byte(number>>16),
byte(number>>24),
)
}

View File

@ -30,10 +30,13 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
case ADD: case ADD:
switch operands := x.Data.(type) { switch operands := x.Data.(type) {
case *RegisterNumber: case *RegisterNumber:
code = x64.AddRegNum8(code, operands.Register, uint8(operands.Number)) code = x64.AddRegNum(code, operands.Register, operands.Number)
}
case *RegisterRegister: case SUB:
// code = x64.AddRegReg64(code, operands.Destination, operands.Source) switch operands := x.Data.(type) {
case *RegisterNumber:
code = x64.SubRegNum(code, operands.Register, operands.Number)
} }
case CALL: case CALL:

View File

@ -3,7 +3,7 @@ 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. // AddRegisterNumber adds a number to the given register.
func (a *Assembler) AddRegisterNumber(reg cpu.Register, number uint64) { func (a *Assembler) AddRegisterNumber(reg cpu.Register, number int) {
a.Instructions = append(a.Instructions, Instruction{ a.Instructions = append(a.Instructions, Instruction{
Mnemonic: ADD, Mnemonic: ADD,
Data: &RegisterNumber{ Data: &RegisterNumber{
@ -13,8 +13,19 @@ func (a *Assembler) AddRegisterNumber(reg cpu.Register, number uint64) {
}) })
} }
// SubRegisterNumber subtracts a number from the given register.
func (a *Assembler) SubRegisterNumber(reg cpu.Register, number int) {
a.Instructions = append(a.Instructions, Instruction{
Mnemonic: SUB,
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 int) {
a.Instructions = append(a.Instructions, Instruction{ a.Instructions = append(a.Instructions, Instruction{
Mnemonic: MOVE, Mnemonic: MOVE,
Data: &RegisterNumber{ Data: &RegisterNumber{

View File

@ -10,6 +10,7 @@ const (
LABEL LABEL
MOVE MOVE
RETURN RETURN
SUB
SYSCALL SYSCALL
) )
@ -34,6 +35,9 @@ func (m Mnemonic) String() string {
case RETURN: case RETURN:
return "return" return "return"
case SUB:
return "sub"
case SYSCALL: case SYSCALL:
return "syscall" return "syscall"
} }

View File

@ -9,7 +9,7 @@ import (
// RegisterNumber operates with a register and a number. // RegisterNumber operates with a register and a number.
type RegisterNumber struct { type RegisterNumber struct {
Register cpu.Register Register cpu.Register
Number uint64 Number int
} }
// String returns a human readable version. // String returns a human readable version.