...
1 package compiler
2
3 import (
4 "github.com/tetratelabs/wazero/internal/asm"
5 "github.com/tetratelabs/wazero/internal/wazeroir"
6 )
7
8
9
10 func compileDropRange(c compiler, raw uint64) (err error) {
11 r := wazeroir.InclusiveRangeFromU64(raw)
12 locationStack := c.runtimeValueLocationStack()
13 if r.Start < 0 {
14 return
15 } else if r.Start == 0 {
16 for i := 0; i <= int(r.End); i++ {
17 if loc := locationStack.pop(); loc.onRegister() {
18 locationStack.releaseRegister(loc)
19 }
20 }
21 return
22 }
23
24
25
26 if err = c.maybeCompileMoveTopConditionalToGeneralPurposeRegister(); err != nil {
27 return
28 }
29
30 dropValues, liveValues := locationStack.dropsLivesForInclusiveRange(r)
31
32
33 for i := range dropValues {
34 dv := &dropValues[i]
35 if dv.onRegister() {
36 locationStack.releaseRegister(dv)
37 }
38 }
39
40
41
42 gpTmp, vecTmp, err := getTemporariesForStackedLiveValues(c, liveValues)
43 if err != nil {
44 return err
45 }
46
47
48 locationStack.sp -= uint64(len(liveValues) + len(dropValues))
49
50
51 for i := range liveValues {
52 live := &liveValues[i]
53 migrateLiveValue(c, live, gpTmp, vecTmp)
54 }
55 return
56 }
57
58
59
60
61 func migrateLiveValue(c compiler, live *runtimeValueLocation, generalPurposeTmpReg, vectorTmpReg asm.Register) {
62 if live.valueType == runtimeValueTypeV128Hi {
63
64 return
65 }
66
67 previouslyOnStack := live.onStack()
68 if previouslyOnStack {
69
70
71 switch live.getRegisterType() {
72 case registerTypeGeneralPurpose:
73 live.setRegister(generalPurposeTmpReg)
74 case registerTypeVector:
75 live.setRegister(vectorTmpReg)
76 }
77
78 c.compileLoadValueOnStackToRegister(live)
79 }
80
81 var newLocation *runtimeValueLocation
82 if live.valueType == runtimeValueTypeV128Lo {
83 newLocation = c.pushVectorRuntimeValueLocationOnRegister(live.register)
84 } else {
85 newLocation = c.pushRuntimeValueLocationOnRegister(live.register, live.valueType)
86 }
87
88 if previouslyOnStack {
89
90
91
92 c.compileReleaseRegisterToStack(newLocation)
93 }
94 }
95
96 func getTemporariesForStackedLiveValues(c compiler, liveValues []runtimeValueLocation) (gpTmp, vecTmp asm.Register, err error) {
97 gpTmp, vecTmp = asm.NilRegister, asm.NilRegister
98 for i := range liveValues {
99 l := &liveValues[i]
100 if l.onStack() {
101 if rt := l.getRegisterType(); rt == registerTypeGeneralPurpose && gpTmp == asm.NilRegister {
102 gpTmp, err = c.allocateRegister(registerTypeGeneralPurpose)
103 if err != nil {
104 return
105 }
106 } else if rt == registerTypeVector && vecTmp == asm.NilRegister {
107 vecTmp, err = c.allocateRegister(registerTypeVector)
108 if err != nil {
109 return
110 }
111 }
112 }
113 }
114 return
115 }
116
117
118 func (v *runtimeValueLocationStack) dropsLivesForInclusiveRange(
119 r wazeroir.InclusiveRange,
120 ) (dropValues, liveValues []runtimeValueLocation) {
121
122 liveValues = v.stack[v.sp-uint64(r.Start) : v.sp]
123
124 dropValues = v.stack[v.sp-uint64(r.End)-1 : v.sp-uint64(r.Start)]
125 return
126 }
127
View as plain text