Something went wrong. Try again.
🌱 A minimal programming language and compiler. git.urbach.dev/cli/q
high-performance programming-language compiler
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104package core
import ( "git.urbach.dev/cli/q/src/ssa" "git.urbach.dev/cli/q/src/token" "git.urbach.dev/cli/q/src/types")
// composeStruct unpacks registers into struct fields.func (f *Function) composeStruct(structType *types.Struct, input *ssa.Parameter, i int, offset int) (*ssa.Struct, int) { fields := make([]ssa.Value, 0, len(structType.Fields))
if structType.Size() > 16 { for _, field := range structType.Fields { nestedType, isNested := types.Unwrap(field.Type).(*types.Struct)
if isNested { nestedInput := &ssa.Parameter{ Name: input.Name + "." + field.Name, Typ: nestedType, Tokens: input.Tokens, Source: input.Source, }
nestedStructure, next := f.composeStruct(nestedType, nestedInput, i, offset) f.Block().Identify(nestedInput.Name, nestedStructure) fields = append(fields, nestedStructure) offset = next + 1 continue }
param := &ssa.Parameter{ Index: uint8(offset + i), Name: input.Name + "." + field.Name, Typ: field.Type, Tokens: input.Tokens, Source: input.Source, }
f.Append(param) f.Block().Identify(param.Name, param) fields = append(fields, param) offset++ }
structure := f.makeStruct(structType, fields, input.Source) return structure, offset - 1 }
var ( param *ssa.Parameter size = 8 )
for _, field := range structType.Fields { fieldSize := field.Type.Size()
if size+fieldSize > 8 { param = &ssa.Parameter{ Index: uint8(offset + i), Typ: field.Type, Tokens: input.Tokens, Source: input.Source, }
f.Append(param) offset++ size = 0 }
var fieldValue ssa.Value
if size == 0 && fieldSize == 8 { fieldValue = param } else { var shifted ssa.Value
if size > 0 { param.Typ = types.UInt sizeValue := f.Append(&ssa.Int{Int: size * 8}) shifted = f.Append(&ssa.BinaryOp{Op: token.Shr, Left: param, Right: sizeValue}) } else { shifted = param }
mask := f.Append(&ssa.Int{Int: (1 << (fieldSize * 8)) - 1}) fieldValue = f.Append(&ssa.BinaryOp{Op: token.And, Left: shifted, Right: mask, Source: param.Source})
if types.IsSigned(field.Type) { typed := f.Append(&ssa.Copy{Value: fieldValue, Typ: field.Type, Source: param.Source, Read: true}) shift := f.Append(&ssa.Int{Int: 64 - fieldSize*8}) leftShifted := f.Append(&ssa.BinaryOp{Op: token.Shl, Left: typed, Right: shift}) fieldValue = f.Append(&ssa.BinaryOp{Op: token.Shr, Left: leftShifted, Right: shift, Source: param.Source}) } }
f.Block().Identify(input.Name+"."+field.Name, fieldValue) fields = append(fields, fieldValue) size += fieldSize }
structure := f.makeStruct(structType, fields, input.Source) return structure, offset - 1}