func (v Target) genSaveFunctionParameters(a *allocator, fn *ssa.Function) { var vals []ssa.Value for _, par := range fn.Parameters() { vals = append(vals, par) } if v.Platform.IsUnixLike() { v.sysVCopyFunctionVals(a, vals, fn.Type().(*types.Signature), false) } else if v.Platform == platform.Windows { v.winSaveFunctionParameters(a, vals, fn.Type().(*types.Signature)) } else { panic("unim") } }
func (v *Target) genFunction(fn *ssa.Function) { if fn.IsPrototype() { return } allocator := newAllocator() allocator.allocate(fn) blockLabelMap := make(map[*ssa.Block]string) for _, block := range fn.Blocks() { blockLabelMap[block] = v.nextLabelName() } v.wnl() v.wop(".globl %s", fn.Name()) v.wop(".align 16, 0x90") // pad with NOPs if v.Platform.IsUnixLike() { v.wop(".type %s,@function", fn.Name()) } v.wlabel(fn.Name()) v.wop("pushq #rbp") v.wop("pushq #rbx") v.wop("pushq #r15") v.wop("movq #rsp, #rbp") v.wop("subq $%d, #rsp", (allocator.stackSize|0xF)+1) retType := fn.Type().(*types.Signature).ReturnType() if sysVClassifyType(retType)[0] == sysVClassMEMORY { v.wop("movq #rdi, #r15") } else if winIsMemory(retType) { v.wop("movq #rdx, #r15") } v.genSaveFunctionParameters(allocator, fn) for _, block := range fn.Blocks() { v.wlabel(blockLabelMap[block]) for _, instr := range block.Instrs() { v.genInstr(allocator, instr, blockLabelMap) } } }