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.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455package core
import ( "git.urbach.dev/cli/q/src/ssa" "git.urbach.dev/cli/q/src/token" "git.urbach.dev/cli/q/src/types")
// decomposeStruct packs struct fields into registers and adds them to `args`.func (f *Function) decomposeStruct(args []ssa.Value, structure *ssa.Struct) []ssa.Value { if structure.Typ.Size() > 16 { for _, field := range structure.Arguments { nested, isNested := field.(*ssa.Struct)
if isNested { args = f.decomposeStruct(args, nested) continue }
args = append(args, field) }
return args }
// Packed integer: Use the first argument, // then bitwise OR with the shifted field values. cursor := structure.Arguments[0] typ := types.Unwrap(structure.Typ).(*types.Struct) size := typ.Fields[0].Type.Size()
for i, field := range structure.Arguments[1:] { fieldSize := typ.Fields[i+1].Type.Size()
if size+fieldSize > 8 { // The field doesn't fit into the register anymore. // We need to use this field as the starting value // for the next argument. args = append(args, cursor) cursor = field size = fieldSize continue }
cursorMask := f.Append(&ssa.Int{Int: (1 << (size * 8)) - 1}) cursor = f.Append(&ssa.BinaryOp{Op: token.And, Left: cursor, Right: cursorMask}) sizeValue := f.Append(&ssa.Int{Int: size * 8}) shifted := f.Append(&ssa.BinaryOp{Op: token.Shl, Left: field, Right: sizeValue}) cursor = f.Append(&ssa.BinaryOp{Op: token.Or, Left: cursor, Right: shifted}) size += fieldSize }
args = append(args, cursor) return args}