Пример #1
0
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)
		}
	}

}