compile_func.go 19.7 KB
Newer Older
3
3dgen 已提交
1 2
// 版权 @2021 凹语言 作者。保留所有权利。

chai2010's avatar
chai2010 已提交
3
package compiler_wat
3
3dgen 已提交
4 5 6 7 8 9 10 11

import (
	"strconv"

	"github.com/wa-lang/wa/internal/constant"
	"github.com/wa-lang/wa/internal/token"
	"github.com/wa-lang/wa/internal/types"

chai2010's avatar
chai2010 已提交
12
	"github.com/wa-lang/wa/internal/backends/compiler_wat/wir"
3
3dgen 已提交
13
	"github.com/wa-lang/wa/internal/backends/compiler_wat/wir/wat"
3
3dgen 已提交
14 15 16 17
	"github.com/wa-lang/wa/internal/logger"
	"github.com/wa-lang/wa/internal/ssa"
)

3
3dgen 已提交
18 19 20 21 22
type valueWrap struct {
	value          wir.Value
	force_register bool
}

3
3dgen 已提交
23
type functionGenerator struct {
3
3dgen 已提交
24
	module *wir.Module
3
3dgen 已提交
25

3
3dgen 已提交
26
	locals_map map[ssa.Value]valueWrap
3
3dgen 已提交
27 28 29 30 31 32

	registers    []wir.Value
	cur_local_id int

	var_block_selector wir.Value
	var_current_block  wir.Value
3
3dgen 已提交
33
	var_rets           []wir.Value
3
3dgen 已提交
34 35 36
}

func newFunctionGenerator(p *Compiler) *functionGenerator {
3
3dgen 已提交
37
	return &functionGenerator{module: p.module, locals_map: make(map[ssa.Value]valueWrap)}
3
3dgen 已提交
38 39
}

3
3dgen 已提交
40
func (g *functionGenerator) getValue(i ssa.Value) valueWrap {
3
3dgen 已提交
41
	if i == nil {
3
3dgen 已提交
42
		return valueWrap{}
3
3dgen 已提交
43 44 45 46 47 48
	}

	if v, ok := g.locals_map[i]; ok {
		return v
	}

49
	if v, ok := g.module.Globals_map[i]; ok {
3
3dgen 已提交
50
		return valueWrap{value: v}
51 52
	}

3
3dgen 已提交
53 54
	switch v := i.(type) {
	case *ssa.Const:
55 56 57
		//if v.Value == nil {
		//	return nil
		//}
3
3dgen 已提交
58

3
3dgen 已提交
59 60 61
		switch t := v.Type().(type) {
		case *types.Basic:
			switch t.Kind() {
3
3dgen 已提交
62

3
3dgen 已提交
63
			case types.Bool:
64
				if constant.BoolVal(v.Value) {
3
3dgen 已提交
65
					return valueWrap{value: wir.NewConst("1", wir.I32{})}
66
				} else {
3
3dgen 已提交
67
					return valueWrap{value: wir.NewConst("0", wir.I32{})}
68
				}
3
3dgen 已提交
69 70 71

			case types.Int:
				val, _ := constant.Int64Val(v.Value)
3
3dgen 已提交
72 73
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.I32{})}

3
3dgen 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
			case types.Uint8:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.U8{})}

			case types.Int8:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.I8{})}

			case types.Uint16:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.U16{})}

			case types.Int16:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.I16{})}

3
3dgen 已提交
90 91 92
			case types.Uint32:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.U32{})}
3
3dgen 已提交
93

chai2010's avatar
chai2010 已提交
94 95
			case types.Int32:
				val, _ := constant.Int64Val(v.Value)
3
3dgen 已提交
96
				if t.Name() == "rune" {
3
3dgen 已提交
97
					return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.RUNE{})}
3
3dgen 已提交
98
				} else {
3
3dgen 已提交
99
					return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.I32{})}
3
3dgen 已提交
100
				}
chai2010's avatar
chai2010 已提交
101

3
3dgen 已提交
102
			case types.Float32:
3
3dgen 已提交
103
				val, _ := constant.Float64Val(v.Value)
3
3dgen 已提交
104
				return valueWrap{value: wir.NewConst(strconv.FormatFloat(val, 'f', -1, 32), wir.F32{})}
3
3dgen 已提交
105 106

			case types.Float64:
3
3dgen 已提交
107
				val, _ := constant.Float64Val(v.Value)
3
3dgen 已提交
108
				return valueWrap{value: wir.NewConst(strconv.FormatFloat(val, 'f', -1, 64), wir.F64{})}
3
3dgen 已提交
109 110

			case types.String, types.UntypedString:
3
3dgen 已提交
111
				val := constant.StringVal(v.Value)
3
3dgen 已提交
112
				return valueWrap{value: wir.NewConst(val, wir.NewString())}
3
3dgen 已提交
113 114

			default:
3
3dgen 已提交
115
				logger.Fatalf("Todo:%T %v", t, t.Kind())
3
3dgen 已提交
116 117
			}

3
3dgen 已提交
118
		case *types.Pointer:
3
3dgen 已提交
119 120 121 122 123
			if v.Value == nil {
				return valueWrap{}
			} else {
				logger.Fatalf("Todo:%T", t)
			}
3
3dgen 已提交
124

3
3dgen 已提交
125
		case *types.Slice:
126
			if v.Value == nil {
3
3dgen 已提交
127
				return valueWrap{value: wir.NewConst("0", wir.NewSlice(wir.ToWType(t.Elem())))}
128
			}
3
3dgen 已提交
129 130 131 132 133 134 135
			logger.Fatalf("Todo:%T", t)

		default:
			logger.Fatalf("Todo:%T", t)
		}

	case ssa.Instruction:
3
3dgen 已提交
136
		nv := valueWrap{value: g.addRegister(wir.ToWType(i.Type()))}
3
3dgen 已提交
137 138
		g.locals_map[i] = nv
		return nv
3
3dgen 已提交
139 140 141

	case *ssa.Function:
		panic("Todo")
3
3dgen 已提交
142 143 144
	}

	logger.Fatal("Value not found:", i)
3
3dgen 已提交
145
	return valueWrap{}
3
3dgen 已提交
146 147
}

3
3dgen 已提交
148
func (g *functionGenerator) genFunction(f *ssa.Function) *wir.Function {
3
3dgen 已提交
149
	var wir_fn wir.Function
150
	if len(f.LinkName()) > 0 {
3
3dgen 已提交
151
		wir_fn.Name = f.LinkName()
152
	} else {
3
3dgen 已提交
153
		wir_fn.Name = GetFnMangleName(f)
154
	}
3
3dgen 已提交
155 156

	rets := f.Signature.Results()
3
3dgen 已提交
157 158 159 160 161 162 163 164 165 166 167 168
	switch rets.Len() {
	case 0:
		break

	case 1:
		wir_fn.Results = append(wir_fn.Results, wir.ToWType(rets.At(0).Type()))

	default:
		typ := wir.ToWType(rets).(wir.Tuple)
		for _, f := range typ.Members {
			wir_fn.Results = append(wir_fn.Results, f.Type())
		}
3
3dgen 已提交
169 170 171
	}

	for _, i := range f.Params {
3
3dgen 已提交
172 173
		pa := valueWrap{value: wir.NewLocal(i.Name(), wir.ToWType(i.Type()))}
		wir_fn.Params = append(wir_fn.Params, pa.value)
3
3dgen 已提交
174 175 176
		g.locals_map[i] = pa
	}

3
3dgen 已提交
177
	g.var_block_selector = wir.NewLocal("$block_selector", wir.I32{})
3
3dgen 已提交
178
	g.registers = append(g.registers, g.var_block_selector)
3
3dgen 已提交
179
	g.var_current_block = wir.NewLocal("$current_block", wir.I32{})
3
3dgen 已提交
180
	g.registers = append(g.registers, g.var_current_block)
3
3dgen 已提交
181 182 183 184 185
	for i, rt := range wir_fn.Results {
		rname := "$ret_" + strconv.Itoa(i)
		r := wir.NewLocal(rname, rt)
		g.var_rets = append(g.var_rets, r)
		g.registers = append(g.registers, r)
3
3dgen 已提交
186 187
	}

3
3dgen 已提交
188
	var block_temp wat.Inst
3
3dgen 已提交
189 190
	//BlockSel:
	{
3
3dgen 已提交
191
		inst := wat.NewInstBlock("$BlockSel")
3
ref WIP  
3dgen 已提交
192
		inst.Insts = append(inst.Insts, g.var_block_selector.EmitPush()...)
3
3dgen 已提交
193 194 195 196 197
		t := make([]int, len(f.Blocks)+1)
		for i := range f.Blocks {
			t[i] = i
		}
		t[len(f.Blocks)] = 0
3
3dgen 已提交
198
		inst.Insts = append(inst.Insts, wat.NewInstBrTable(t))
3
3dgen 已提交
199 200 201 202
		block_temp = inst
	}

	for i, b := range f.Blocks {
3
3dgen 已提交
203
		block := wat.NewInstBlock("$Block_" + strconv.Itoa(i))
3
3dgen 已提交
204 205 206 207 208 209 210
		block.Insts = append(block.Insts, block_temp)
		block.Insts = append(block.Insts, g.genBlock(b)...)
		block_temp = block
	}

	//BlockDisp
	{
3
3dgen 已提交
211
		inst := wat.NewInstLoop("$BlockDisp")
3
3dgen 已提交
212 213 214 215 216 217
		inst.Insts = append(inst.Insts, block_temp)
		block_temp = inst
	}

	//BlockFnBody
	{
3
3dgen 已提交
218
		inst := wat.NewInstBlock("$BlockFnBody")
3
3dgen 已提交
219 220 221 222
		inst.Insts = append(inst.Insts, block_temp)
		block_temp = inst
	}

3
ref WIP  
3dgen 已提交
223 224 225 226
	for _, i := range g.registers {
		wir_fn.Insts = append(wir_fn.Insts, i.EmitInit()...)
	}

3
3dgen 已提交
227
	wir_fn.Insts = append(wir_fn.Insts, block_temp)
3
3dgen 已提交
228

3
3dgen 已提交
229 230
	for _, r := range g.var_rets {
		wir_fn.Insts = append(wir_fn.Insts, r.EmitPush()...)
3
ref WIP  
3dgen 已提交
231 232 233 234
	}

	for _, i := range g.registers {
		wir_fn.Insts = append(wir_fn.Insts, i.EmitRelease()...)
3
3dgen 已提交
235 236
	}

3
3dgen 已提交
237 238 239 240
	for _, i := range wir_fn.Params {
		wir_fn.Insts = append(wir_fn.Insts, i.EmitRelease()...)
	}

3
3dgen 已提交
241 242
	wir_fn.Locals = g.registers

3
3dgen 已提交
243
	return &wir_fn
3
3dgen 已提交
244 245
}

3
3dgen 已提交
246
func (g *functionGenerator) genBlock(block *ssa.BasicBlock) []wat.Inst {
3
3dgen 已提交
247 248 249 250 251
	if len(block.Instrs) == 0 {
		logger.Fatalf("Block:%s is empty", block)
	}

	cur_block_assigned := false
3
3dgen 已提交
252
	var b []wat.Inst
3
3dgen 已提交
253 254 255
	for _, inst := range block.Instrs {
		if _, ok := inst.(*ssa.Phi); !ok {
			if !cur_block_assigned {
3
3dgen 已提交
256
				b = append(b, wir.EmitAssginValue(g.var_current_block, wir.NewConst(strconv.Itoa(block.Index), wir.I32{}))...)
3
3dgen 已提交
257
				b = append(b, wat.NewBlank())
3
3dgen 已提交
258 259 260 261 262 263 264 265 266 267
				cur_block_assigned = true
			}
		}

		b = append(b, g.genInstruction(inst)...)
	}
	return b

}

3
3dgen 已提交
268 269 270
func (g *functionGenerator) genInstruction(inst ssa.Instruction) (insts []wat.Inst) {
	insts = append(insts, wat.NewComment(inst.String()))

3
3dgen 已提交
271 272 273
	switch inst := inst.(type) {

	case *ssa.If:
3
3dgen 已提交
274
		insts = append(insts, g.genIf(inst)...)
3
3dgen 已提交
275 276

	case *ssa.Store:
3
3dgen 已提交
277
		insts = append(insts, g.genStore(inst)...)
3
3dgen 已提交
278 279

	case *ssa.Jump:
3
3dgen 已提交
280
		insts = append(insts, g.genJump(inst)...)
3
3dgen 已提交
281 282

	case *ssa.Return:
3
3dgen 已提交
283
		insts = append(insts, g.genReturn(inst)...)
3
3dgen 已提交
284 285 286

	case ssa.Value:
		s, t := g.genValue(inst)
3
3dgen 已提交
287
		if t != nil && !t.Equal(wir.VOID{}) {
3
3dgen 已提交
288
			if v, ok := g.locals_map[inst]; ok {
3
3dgen 已提交
289
				if !v.value.Type().Equal(t) {
3
3dgen 已提交
290 291
					panic("Type not match")
				}
3
3dgen 已提交
292
				s = append(s, v.value.EmitPop()...)
3
3dgen 已提交
293 294
			} else {
				nv := g.addRegister(t)
3
3dgen 已提交
295
				g.locals_map[inst] = valueWrap{value: nv}
3
3dgen 已提交
296 297
				s = append(s, nv.EmitPop()...)
			}
3
3dgen 已提交
298
		}
3
3dgen 已提交
299
		insts = append(insts, s...)
3
3dgen 已提交
300 301 302 303

	default:
		logger.Fatal("Todo:", inst.String())
	}
3
3dgen 已提交
304 305
	insts = append(insts, wat.NewBlank())
	return
3
3dgen 已提交
306 307
}

3
3dgen 已提交
308 309 310 311
func (g *functionGenerator) genValue(v ssa.Value) ([]wat.Inst, wir.ValueType) {
	//if _, ok := g.locals_map[v]; ok {
	//	logger.Printf("Instruction already exist:%s\n", v)
	//}
3
3dgen 已提交
312 313 314

	switch v := v.(type) {
	case *ssa.UnOp:
3
Ref WIP  
3dgen 已提交
315
		return g.genUnOp(v)
3
3dgen 已提交
316 317 318 319 320 321 322 323 324 325

	case *ssa.BinOp:
		return g.genBinOp(v)

	case *ssa.Call:
		return g.genCall(v)

	case *ssa.Phi:
		return g.genPhi(v)

3
Ref WIP  
3dgen 已提交
326 327 328
	case *ssa.Alloc:
		return g.genAlloc(v)

3
3dgen 已提交
329 330 331
	case *ssa.Extract:
		return g.genExtract(v)

3
3dgen 已提交
332 333 334
	case *ssa.Field:
		return g.genFiled(v)

3
3dgen 已提交
335
	case *ssa.FieldAddr:
3
3dgen 已提交
336
		return g.genFieldAddr(v)
3
3dgen 已提交
337 338

	case *ssa.IndexAddr:
3
3dgen 已提交
339
		return g.genIndexAddr(v)
3
3dgen 已提交
340 341

	case *ssa.Slice:
342
		return g.genSlice(v)
3
3dgen 已提交
343

3
3dgen 已提交
344 345 346 347 348 349
	case *ssa.Lookup:
		return g.genLookup(v)

	case *ssa.Convert:
		return g.genConvert(v)

3
3dgen 已提交
350 351
	case *ssa.ChangeType:
		return g.genChangeType(v)
3
3dgen 已提交
352 353 354 355 356 357
	}

	logger.Fatalf("Todo: %v, type: %T", v, v)
	return nil, nil
}

3
3dgen 已提交
358
func (g *functionGenerator) genUnOp(inst *ssa.UnOp) (insts []wat.Inst, ret_type wir.ValueType) {
3
Ref WIP  
3dgen 已提交
359 360
	switch inst.Op {
	case token.MUL: //*x
361
		return g.genLoad(inst.X)
3
3dgen 已提交
362 363 364

	case token.SUB:
		x := g.getValue(inst.X)
3
3dgen 已提交
365
		return wir.EmitUnOp(x.value, wat.OpCodeSub)
3
3dgen 已提交
366 367 368

	default:
		logger.Fatal("Todo")
3
Ref WIP  
3dgen 已提交
369 370
	}

3
3dgen 已提交
371
	return
3
Ref WIP  
3dgen 已提交
372 373
}

3
3dgen 已提交
374
func (g *functionGenerator) genBinOp(inst *ssa.BinOp) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
375 376 377 378 379 380 381
	x := g.getValue(inst.X)
	y := g.getValue(inst.Y)

	switch inst.X.Type().Underlying().(type) {
	case *types.Basic:
		switch inst.Op {
		case token.ADD:
3
3dgen 已提交
382
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeAdd)
3
3dgen 已提交
383 384

		case token.SUB:
3
3dgen 已提交
385
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeSub)
3
3dgen 已提交
386 387

		case token.MUL:
3
3dgen 已提交
388
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeMul)
3
3dgen 已提交
389 390

		case token.QUO:
3
3dgen 已提交
391
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeQuo)
3
3dgen 已提交
392 393

		case token.REM:
3
3dgen 已提交
394
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeRem)
3
3dgen 已提交
395 396

		case token.EQL:
3
3dgen 已提交
397
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeEql)
3
3dgen 已提交
398 399

		case token.NEQ:
3
3dgen 已提交
400
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeNe)
3
3dgen 已提交
401 402

		case token.LSS:
3
3dgen 已提交
403
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeLt)
3
3dgen 已提交
404 405

		case token.GTR:
3
3dgen 已提交
406
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeGt)
3
3dgen 已提交
407 408

		case token.LEQ:
3
3dgen 已提交
409
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeLe)
3
3dgen 已提交
410 411

		case token.GEQ:
3
3dgen 已提交
412
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeGe)
3
3dgen 已提交
413 414 415 416 417 418 419 420 421 422
		}

	default:
		logger.Fatalf("Todo: %v, type: %T, token:%v", inst, inst, inst.Op)
	}

	logger.Fatalf("Todo: %v, type: %T, token:%v", inst, inst, inst.Op)
	return nil, nil
}

3
3dgen 已提交
423
func (g *functionGenerator) genCall(inst *ssa.Call) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
424 425 426 427 428 429 430
	if inst.Call.IsInvoke() {
		logger.Fatal("Todo: genCall(), Invoke")
	}

	switch inst.Call.Value.(type) {
	case *ssa.Function:
		ret_type := wir.ToWType(inst.Call.Signature().Results())
3
3dgen 已提交
431
		var insts []wat.Inst
3
3dgen 已提交
432
		for _, v := range inst.Call.Args {
3
3dgen 已提交
433
			insts = append(insts, g.getValue(v).value.EmitPush()...)
3
3dgen 已提交
434
		}
435 436
		callee := inst.Call.StaticCallee()
		if len(callee.LinkName()) > 0 {
3
3dgen 已提交
437
			insts = append(insts, wat.NewInstCall(callee.LinkName()))
438
		} else {
3
3dgen 已提交
439
			insts = append(insts, wat.NewInstCall(GetFnMangleName(callee)))
440
		}
3
3dgen 已提交
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
		return insts, ret_type

	case *ssa.Builtin:
		return g.genBuiltin(inst.Common())

	case *ssa.MakeClosure:
		logger.Fatal("Todo: genCall(), MakeClosure")

	default:
		logger.Fatalf("Todo: type:%T", inst.Call.Value)
	}

	logger.Fatal("Todo")

	return nil, nil
}

458
func (g *functionGenerator) genBuiltin(call *ssa.CallCommon) (insts []wat.Inst, ret_type wir.ValueType) {
3
3dgen 已提交
459 460 461 462
	switch call.Value.Name() {
	case "print", "println":
		for _, arg := range call.Args {
			arg := g.getValue(arg)
3
3dgen 已提交
463
			switch arg.value.Type().(type) {
3
3dgen 已提交
464
			case wir.I32:
3
3dgen 已提交
465
				insts = append(insts, arg.value.EmitPush()...)
3
3dgen 已提交
466
				insts = append(insts, wat.NewInstCall("$runtime.waPrintI32"))
3
3dgen 已提交
467

3
3dgen 已提交
468
			case wir.F32:
3
3dgen 已提交
469
				insts = append(insts, arg.value.EmitPush()...)
3
3dgen 已提交
470
				insts = append(insts, wat.NewInstCall("$runtime.waPrintF32"))
3
3dgen 已提交
471 472

			case wir.F64:
3
3dgen 已提交
473
				insts = append(insts, arg.value.EmitPush()...)
3
3dgen 已提交
474
				insts = append(insts, wat.NewInstCall("$runtime.waPrintF64"))
3
3dgen 已提交
475

3
3dgen 已提交
476
			case wir.RUNE:
3
3dgen 已提交
477
				insts = append(insts, arg.value.EmitPush()...)
3
3dgen 已提交
478
				insts = append(insts, wat.NewInstCall("$runtime.waPrintRune"))
3
3dgen 已提交
479

3
3dgen 已提交
480
			case wir.String:
3
3dgen 已提交
481
				insts = append(insts, wir.EmitPrintString(arg.value)...)
3
3dgen 已提交
482

3
3dgen 已提交
483
			default:
3
3dgen 已提交
484
				logger.Fatalf("Todo: print(%T)", arg.value.Type())
3
3dgen 已提交
485 486 487 488
			}
		}

		if call.Value.Name() == "println" {
3
3dgen 已提交
489
			insts = append(insts, wir.NewConst(strconv.Itoa('\n'), wir.I32{}).EmitPush()...)
3
3dgen 已提交
490
			insts = append(insts, wat.NewInstCall("$runtime.waPrintRune"))
3
3dgen 已提交
491
		}
492 493 494 495 496 497
		ret_type = wir.VOID{}

	case "append":
		if len(call.Args) != 2 {
			panic("len(call.Args) != 2")
		}
3
3dgen 已提交
498
		insts, ret_type = wir.EmitGenAppend(g.getValue(call.Args[0]).value, g.getValue(call.Args[1]).value)
499 500 501 502 503

	case "len":
		if len(call.Args) != 1 {
			panic("len(call.Args) != 1")
		}
3
3dgen 已提交
504
		insts = wir.EmitGenLen(g.getValue(call.Args[0]).value)
505
		ret_type = wir.I32{}
3
3dgen 已提交
506

507 508
	default:
		logger.Fatal("Todo:", call.Value)
3
3dgen 已提交
509
	}
510
	return
3
3dgen 已提交
511 512
}

3
3dgen 已提交
513 514
func (g *functionGenerator) genPhiIter(preds []int, values []wir.Value) []wat.Inst {
	var insts []wat.Inst
3
3dgen 已提交
515

3
3dgen 已提交
516
	cond, _ := wir.EmitBinOp(g.var_current_block, wir.NewConst(strconv.Itoa(preds[0]), wir.I32{}), wat.OpCodeEql)
3
3dgen 已提交
517 518
	insts = append(insts, cond...)

3
ref WIP  
3dgen 已提交
519
	trueInsts := values[0].EmitPush()
3
3dgen 已提交
520
	var falseInsts []wat.Inst
3
3dgen 已提交
521
	if len(preds) == 2 {
3
ref WIP  
3dgen 已提交
522
		falseInsts = values[1].EmitPush()
3
3dgen 已提交
523
	} else {
3
3dgen 已提交
524
		falseInsts = g.genPhiIter(preds[1:], values[1:])
3
3dgen 已提交
525
	}
3
3dgen 已提交
526
	insts = append(insts, wat.NewInstIf(trueInsts, falseInsts, values[0].Type().Raw()))
3
3dgen 已提交
527 528 529

	return insts
}
3
3dgen 已提交
530
func (g *functionGenerator) genPhi(inst *ssa.Phi) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
531 532 533 534
	var preds []int
	var values []wir.Value
	for i, v := range inst.Edges {
		preds = append(preds, inst.Block().Preds[i].Index)
3
3dgen 已提交
535
		values = append(values, g.getValue(v).value)
3
3dgen 已提交
536 537 538 539
	}
	return g.genPhiIter(preds, values), wir.ToWType(inst.Type())
}

3
3dgen 已提交
540 541
func (g *functionGenerator) genReturn(inst *ssa.Return) []wat.Inst {
	var insts []wat.Inst
3
3dgen 已提交
542

3
3dgen 已提交
543 544 545
	if len(inst.Results) != len(g.var_rets) {
		panic("len(inst.Results) != len(g.var_rets)")
	}
3
3dgen 已提交
546

3
3dgen 已提交
547 548
	for i := range inst.Results {
		insts = append(insts, wir.EmitAssginValue(g.var_rets[i], g.getValue(inst.Results[i]).value)...)
3
3dgen 已提交
549 550
	}

3
3dgen 已提交
551
	insts = append(insts, wat.NewInstBr("$BlockFnBody"))
3
3dgen 已提交
552 553 554
	return insts
}

3
3dgen 已提交
555 556 557 558 559 560 561 562 563 564 565
func (g *functionGenerator) genLoad(Addr ssa.Value) (insts []wat.Inst, ret_type wir.ValueType) {
	addr := g.getValue(Addr)

	if addr.force_register {
		insts = append(insts, addr.value.EmitPush()...)
		ret_type = addr.value.Type()
	} else {
		insts, ret_type = wir.EmitLoad(addr.value)
	}

	return
566 567
}

3
ref WIP  
3dgen 已提交
568
func (g *functionGenerator) genStore(inst *ssa.Store) []wat.Inst {
3
3dgen 已提交
569 570 571 572 573 574 575 576
	addr := g.getValue(inst.Addr)
	val := g.getValue(inst.Val)

	if addr.force_register {
		return wir.EmitAssginValue(addr.value, val.value)
	} else {
		return wir.EmitStore(addr.value, val.value)
	}
3
ref WIP  
3dgen 已提交
577 578
}

3
3dgen 已提交
579
func (g *functionGenerator) genIf(inst *ssa.If) []wat.Inst {
3
3dgen 已提交
580
	cond := g.getValue(inst.Cond)
3
3dgen 已提交
581
	if !cond.value.Type().Equal(wir.I32{}) {
3
3dgen 已提交
582 583 584
		logger.Fatal("cond.type() != i32")
	}

3
3dgen 已提交
585
	insts := cond.value.EmitPush()
3
3dgen 已提交
586 587
	instsTrue := g.genJumpID(inst.Block().Index, inst.Block().Succs[0].Index)
	instsFalse := g.genJumpID(inst.Block().Index, inst.Block().Succs[1].Index)
3
3dgen 已提交
588
	insts = append(insts, wat.NewInstIf(instsTrue, instsFalse, nil))
3
3dgen 已提交
589 590 591 592

	return insts
}

3
3dgen 已提交
593
func (g *functionGenerator) genJump(inst *ssa.Jump) []wat.Inst {
3
3dgen 已提交
594 595 596
	return g.genJumpID(inst.Block().Index, inst.Block().Succs[0].Index)
}

3
3dgen 已提交
597 598
func (g *functionGenerator) genJumpID(cur, dest int) []wat.Inst {
	var insts []wat.Inst
3
3dgen 已提交
599 600

	if cur >= dest {
3
3dgen 已提交
601
		insts = wir.EmitAssginValue(g.var_block_selector, wir.NewConst(strconv.Itoa(dest), wir.I32{}))
3
3dgen 已提交
602
		insts = append(insts, wat.NewInstBr("$BlockDisp"))
3
3dgen 已提交
603
	} else {
3
3dgen 已提交
604
		insts = append(insts, wat.NewInstBr("$Block_"+strconv.Itoa(dest-1)))
3
3dgen 已提交
605 606 607 608 609
	}

	return insts
}

3
3dgen 已提交
610 611 612 613 614 615 616 617
func (g *functionGenerator) genAlloc(inst *ssa.Alloc) (insts []wat.Inst, ret_type wir.ValueType) {
	typ := wir.ToWType(inst.Type().(*types.Pointer).Elem())
	if inst.Parent().ForceRegister() {
		nv := g.addRegister(typ)
		g.locals_map[inst] = valueWrap{value: nv, force_register: true}
		insts = append(insts, nv.EmitRelease()...)
		insts = append(insts, nv.EmitInit()...)
		ret_type = nil
3
Ref WIP  
3dgen 已提交
618
	} else {
3
3dgen 已提交
619 620 621 622 623
		if inst.Heap {
			insts, ret_type = wir.EmitHeapAlloc(typ)
		} else {
			insts, ret_type = wir.EmitStackAlloc(typ)
		}
3
Ref WIP  
3dgen 已提交
624
	}
3
3dgen 已提交
625 626

	return
3
Ref WIP  
3dgen 已提交
627 628
}

3
3dgen 已提交
629 630 631 632 633
func (g *functionGenerator) genExtract(inst *ssa.Extract) ([]wat.Inst, wir.ValueType) {
	v := g.getValue(inst.Tuple)
	return wir.EmitGenExtract(v.value, inst.Index)
}

3
3dgen 已提交
634 635 636 637 638
func (g *functionGenerator) genFiled(inst *ssa.Field) ([]wat.Inst, wir.ValueType) {
	x := g.getValue(inst.X)
	field := inst.X.Type().Underlying().(*types.Struct).Field(inst.Field)
	fieldname := field.Name()
	if field.Embedded() {
3
3dgen 已提交
639 640 641
		if _, ok := field.Type().(*types.Named); ok {
			fieldname = wir.GetPkgMangleName(field.Pkg().Path()) + fieldname
		}
3
3dgen 已提交
642 643 644
		fieldname = "$" + fieldname
	}

3
3dgen 已提交
645
	return wir.EmitGenField(x.value, fieldname)
3
3dgen 已提交
646 647
}

3
3dgen 已提交
648 649 650 651
func (g *functionGenerator) genFieldAddr(inst *ssa.FieldAddr) ([]wat.Inst, wir.ValueType) {
	field := inst.X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct).Field(inst.Field)
	fieldname := field.Name()
	if field.Embedded() {
3
3dgen 已提交
652 653 654
		if _, ok := field.Type().(*types.Named); ok {
			fieldname = wir.GetPkgMangleName(field.Pkg().Path()) + fieldname
		}
3
3dgen 已提交
655 656 657
		fieldname = "$" + fieldname
	}

3
3dgen 已提交
658 659 660 661 662 663 664 665
	x := g.getValue(inst.X)
	if x.force_register {
		nv := wir.ExtractField(x.value, fieldname)
		g.locals_map[inst] = valueWrap{value: nv, force_register: true}
		return nil, nil
	} else {
		return wir.EmitGenFieldAddr(x.value, fieldname)
	}
3
3dgen 已提交
666 667
}

3
3dgen 已提交
668
func (g *functionGenerator) genIndexAddr(inst *ssa.IndexAddr) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
669 670 671 672 673
	if inst.Parent().ForceRegister() {
		logger.Fatal("ssa.IndexAddr is not available in ForceRegister-mode")
		return nil, nil
	}

3
3dgen 已提交
674 675 676
	x := g.getValue(inst.X)
	id := g.getValue(inst.Index)

3
3dgen 已提交
677
	return wir.EmitGenIndexAddr(x.value, id.value)
3
3dgen 已提交
678 679
}

680
func (g *functionGenerator) genSlice(inst *ssa.Slice) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
681 682 683 684 685
	if inst.Parent().ForceRegister() {
		logger.Fatal("ssa.Slice is not available in ForceRegister-mode")
		return nil, nil
	}

686 687 688
	x := g.getValue(inst.X)
	var low, high wir.Value
	if inst.Low != nil {
3
3dgen 已提交
689
		low = g.getValue(inst.Low).value
690 691
	}
	if inst.High != nil {
3
3dgen 已提交
692
		high = g.getValue(inst.High).value
693 694
	}

3
3dgen 已提交
695
	return wir.EmitGenSlice(x.value, low, high)
696 697
}

3
3dgen 已提交
698 699 700 701 702 703 704 705 706 707 708 709 710 711
func (g *functionGenerator) genLookup(inst *ssa.Lookup) ([]wat.Inst, wir.ValueType) {
	x := g.getValue(inst.X)
	index := g.getValue(inst.Index)

	return wir.EmitGenLookup(x.value, index.value, inst.CommaOk)
}

func (g *functionGenerator) genConvert(inst *ssa.Convert) (insts []wat.Inst, ret_type wir.ValueType) {
	x := g.getValue(inst.X)
	ret_type = wir.ToWType(inst.Type())
	insts = wir.EmitGenConvert(x.value, ret_type)
	return
}

3
3dgen 已提交
712 713 714 715 716 717 718
func (g *functionGenerator) genChangeType(inst *ssa.ChangeType) (insts []wat.Inst, ret_type wir.ValueType) {
	ret_type = wir.ToWType(inst.Type())
	x := g.getValue(inst.X)
	insts = append(insts, x.value.EmitPush()...)
	return
}

3
3dgen 已提交
719
func (g *functionGenerator) addRegister(typ wir.ValueType) wir.Value {
3
3dgen 已提交
720
	defer func() { g.cur_local_id++ }()
3
3dgen 已提交
721
	name := "$T_" + strconv.Itoa(g.cur_local_id)
3
3dgen 已提交
722
	v := wir.NewLocal(name, typ)
3
3dgen 已提交
723 724 725
	g.registers = append(g.registers, v)
	return v
}
3
3dgen 已提交
726 727 728 729 730 731

func (g *functionGenerator) genGetter(f *ssa.Function) *wir.Function {
	var wir_fn wir.Function
	if len(f.LinkName()) > 0 {
		wir_fn.Name = f.LinkName()
	} else {
3
3dgen 已提交
732
		wir_fn.Name = GetFnMangleName(f)
3
3dgen 已提交
733 734 735 736 737 738 739
	}

	rets := f.Signature.Results()
	if rets.Len() > 1 {
		logger.Fatal("rets.Len() > 1")
		return nil
	}
3
3dgen 已提交
740 741
	rtype := wir.ToWType(rets)
	wir_fn.Results = append(wir_fn.Results, rtype)
3
3dgen 已提交
742 743 744 745 746 747 748 749 750

	if len(f.Params) != 1 {
		logger.Fatal("len(f.Params) != 1")
		return nil
	}
	if !wir.ToWType(f.Params[0].Type()).Equal(wir.U32{}) {
		logger.Fatal("addr_type != U32")
		return nil
	}
3
3dgen 已提交
751
	addr := wir.NewLocal("addr", wir.NewPointer(rtype))
3
3dgen 已提交
752 753 754 755 756 757 758 759 760 761 762 763 764
	wir_fn.Params = append(wir_fn.Params, addr)

	insts, _ := wir.EmitLoad(addr)
	wir_fn.Insts = append(wir_fn.Insts, insts...)

	return &wir_fn
}

func (g *functionGenerator) genSetter(f *ssa.Function) *wir.Function {
	var wir_fn wir.Function
	if len(f.LinkName()) > 0 {
		wir_fn.Name = f.LinkName()
	} else {
3
3dgen 已提交
765
		wir_fn.Name = GetFnMangleName(f)
3
3dgen 已提交
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
	}

	rets := f.Signature.Results()
	if rets.Len() > 0 {
		logger.Fatal("rets.Len() > 0")
		return nil
	}

	if len(f.Params) != 2 {
		logger.Fatal("len(f.Params) != 2")
		return nil
	}
	if !wir.ToWType(f.Params[0].Type()).Equal(wir.U32{}) {
		logger.Fatal("addr_type != U32")
		return nil
	}

	value_type := wir.ToWType(f.Params[1].Type())

	addr := wir.NewLocal("addr", wir.NewPointer(value_type))
	wir_fn.Params = append(wir_fn.Params, addr)

	value := wir.NewLocal("data", value_type)
	wir_fn.Params = append(wir_fn.Params, value)

	insts := wir.EmitStore(addr, value)
	wir_fn.Insts = append(wir_fn.Insts, insts...)

	return &wir_fn
}