Пример #1
0
func (v *gen) genFunction(fn *ir.Function) {
	v.nl()
	v.emitDirec(".globl %s", fn.Name())
	v.emitDirec(".type %s,@function", fn.Name())

	v.emitLabel("%s:", fn.Name())
	// setup the stack
	v.emitOp("pushl @ebp")
	v.emitOp("movl @esp, @ebp")
	v.emitOp("pusha")
	v.emitOp("andl $-16, @esp") // align SP to 16-byte boundary

	alloc := v.target.newAllocator()
	alloc.allocFunction(fn)
	v.emitOp("subl $%d, @esp", alloc.stackSize) // actually allocate the stack vars

	labelNames := make(map[*ir.Block]string)
	for _, block := range fn.Blocks() {
		labelNames[block] = v.nextLabelName()
	}

	for _, block := range fn.Blocks() {
		v.genBlock(block, alloc, labelNames)
	}
}
Пример #2
0
func (v Target) functionParameterStackSize(fn *ir.Function) int {
	res := 0
	for _, par := range fn.Parameters() {
		res += v.TypeSize(par.Type())
	}
	return res
}
Пример #3
0
func (v *allocator) allocFunction(fn *ir.Function) {
	switch fn.CallConv() {
	case ir.CCallConv, ir.X86_StdCallConv:
		parPos := 8
		for _, par := range fn.Parameters() {
			v.locs[par] = &location{
				stackPos: parPos,
			}

			bytes := v.target.TypeSize(par.Type())
			if bytes%2 == 1 {
				bytes++
			}
			parPos += bytes
		}
	default:
		panic("x86 target does not support " + fn.CallConv().String())
	}

	for _, block := range fn.Blocks() {
		for _, instr := range block.Instrs() {
			if !instr.Type().IsVoid() {
				v.addValue(instr)
			}
		}
	}
}