github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/engine/wazevo/backend/abi_test.go (about) 1 package backend 2 3 import ( 4 "testing" 5 6 "github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc" 7 "github.com/tetratelabs/wazero/internal/engine/wazevo/ssa" 8 "github.com/tetratelabs/wazero/internal/testing/require" 9 ) 10 11 const ( 12 x0 = regalloc.RealRegInvalid + 1 + iota 13 x1 14 x2 15 x3 16 x4 17 x5 18 x6 19 x7 20 x8 21 x9 22 v0 23 v1 24 v2 25 v3 26 v4 27 v5 28 v6 29 v7 30 v8 31 v9 32 ) 33 34 var ( 35 x0VReg = regalloc.FromRealReg(x0, regalloc.RegTypeInt) 36 x1VReg = regalloc.FromRealReg(x1, regalloc.RegTypeInt) 37 x2VReg = regalloc.FromRealReg(x2, regalloc.RegTypeInt) 38 x3VReg = regalloc.FromRealReg(x3, regalloc.RegTypeInt) 39 x4VReg = regalloc.FromRealReg(x4, regalloc.RegTypeInt) 40 x5VReg = regalloc.FromRealReg(x5, regalloc.RegTypeInt) 41 x6VReg = regalloc.FromRealReg(x6, regalloc.RegTypeInt) 42 x7VReg = regalloc.FromRealReg(x7, regalloc.RegTypeInt) 43 44 v0VReg = regalloc.FromRealReg(v0, regalloc.RegTypeFloat) 45 v1VReg = regalloc.FromRealReg(v1, regalloc.RegTypeFloat) 46 v2VReg = regalloc.FromRealReg(v2, regalloc.RegTypeFloat) 47 v3VReg = regalloc.FromRealReg(v3, regalloc.RegTypeFloat) 48 v4VReg = regalloc.FromRealReg(v4, regalloc.RegTypeFloat) 49 v5VReg = regalloc.FromRealReg(v5, regalloc.RegTypeFloat) 50 v6VReg = regalloc.FromRealReg(v6, regalloc.RegTypeFloat) 51 v7VReg = regalloc.FromRealReg(v7, regalloc.RegTypeFloat) 52 53 intParamResultRegs = []regalloc.RealReg{x0, x1, x2, x3, x4, x5, x6, x7} 54 floatParamResultRegs = []regalloc.RealReg{v0, v1, v2, v3, v4, v5, v6, v7} 55 ) 56 57 func TestAbiImpl_init(t *testing.T) { 58 for _, tc := range []struct { 59 name string 60 sig *ssa.Signature 61 exp FunctionABI 62 }{ 63 { 64 name: "empty sig", 65 sig: &ssa.Signature{}, 66 exp: FunctionABI{}, 67 }, 68 { 69 name: "small sig", 70 sig: &ssa.Signature{ 71 Params: []ssa.Type{ssa.TypeI32, ssa.TypeF32, ssa.TypeI32}, 72 Results: []ssa.Type{ssa.TypeI64, ssa.TypeF64}, 73 }, 74 exp: FunctionABI{ 75 Args: []ABIArg{ 76 {Index: 0, Kind: ABIArgKindReg, Reg: x0VReg, Type: ssa.TypeI32}, 77 {Index: 1, Kind: ABIArgKindReg, Reg: v0VReg, Type: ssa.TypeF32}, 78 {Index: 2, Kind: ABIArgKindReg, Reg: x1VReg, Type: ssa.TypeI32}, 79 }, 80 Rets: []ABIArg{ 81 {Index: 0, Kind: ABIArgKindReg, Reg: x0VReg, Type: ssa.TypeI64}, 82 {Index: 1, Kind: ABIArgKindReg, Reg: v0VReg, Type: ssa.TypeF64}, 83 }, 84 ArgIntRealRegs: 2, ArgFloatRealRegs: 1, 85 RetIntRealRegs: 1, RetFloatRealRegs: 1, 86 }, 87 }, 88 { 89 name: "regs stack mix and match", 90 sig: &ssa.Signature{ 91 Params: []ssa.Type{ 92 ssa.TypeI32, ssa.TypeF32, 93 ssa.TypeI64, ssa.TypeF64, 94 ssa.TypeI32, ssa.TypeF32, 95 ssa.TypeI64, ssa.TypeF64, 96 ssa.TypeI32, ssa.TypeF32, 97 ssa.TypeI64, ssa.TypeF64, 98 ssa.TypeI32, ssa.TypeF32, 99 ssa.TypeI64, ssa.TypeF64, 100 ssa.TypeI32, ssa.TypeF32, 101 ssa.TypeI64, ssa.TypeF64, 102 ssa.TypeI32, ssa.TypeF32, 103 ssa.TypeI64, ssa.TypeF64, 104 ssa.TypeI32, ssa.TypeF32, 105 ssa.TypeI64, ssa.TypeF64, 106 ssa.TypeI32, ssa.TypeF32, 107 ssa.TypeI64, ssa.TypeF64, 108 }, 109 Results: []ssa.Type{ 110 ssa.TypeI32, ssa.TypeF32, 111 ssa.TypeI64, ssa.TypeF64, 112 ssa.TypeI32, ssa.TypeF32, 113 ssa.TypeI64, ssa.TypeF64, 114 ssa.TypeI32, ssa.TypeF32, 115 ssa.TypeI64, ssa.TypeF64, 116 ssa.TypeI32, ssa.TypeF32, 117 ssa.TypeI64, ssa.TypeF64, 118 ssa.TypeI32, ssa.TypeF32, 119 ssa.TypeI64, ssa.TypeF64, 120 ssa.TypeI32, ssa.TypeF32, 121 ssa.TypeI64, ssa.TypeF64, 122 ssa.TypeI32, ssa.TypeF32, 123 ssa.TypeI64, ssa.TypeF64, 124 ssa.TypeI32, ssa.TypeF32, 125 ssa.TypeI64, ssa.TypeF64, 126 }, 127 }, 128 exp: FunctionABI{ 129 ArgStackSize: 128, RetStackSize: 128, 130 Args: []ABIArg{ 131 {Index: 0, Kind: ABIArgKindReg, Reg: x0VReg, Type: ssa.TypeI32}, 132 {Index: 1, Kind: ABIArgKindReg, Reg: v0VReg, Type: ssa.TypeF32}, 133 {Index: 2, Kind: ABIArgKindReg, Reg: x1VReg, Type: ssa.TypeI64}, 134 {Index: 3, Kind: ABIArgKindReg, Reg: v1VReg, Type: ssa.TypeF64}, 135 {Index: 4, Kind: ABIArgKindReg, Reg: x2VReg, Type: ssa.TypeI32}, 136 {Index: 5, Kind: ABIArgKindReg, Reg: v2VReg, Type: ssa.TypeF32}, 137 {Index: 6, Kind: ABIArgKindReg, Reg: x3VReg, Type: ssa.TypeI64}, 138 {Index: 7, Kind: ABIArgKindReg, Reg: v3VReg, Type: ssa.TypeF64}, 139 {Index: 8, Kind: ABIArgKindReg, Reg: x4VReg, Type: ssa.TypeI32}, 140 {Index: 9, Kind: ABIArgKindReg, Reg: v4VReg, Type: ssa.TypeF32}, 141 {Index: 10, Kind: ABIArgKindReg, Reg: x5VReg, Type: ssa.TypeI64}, 142 {Index: 11, Kind: ABIArgKindReg, Reg: v5VReg, Type: ssa.TypeF64}, 143 {Index: 12, Kind: ABIArgKindReg, Reg: x6VReg, Type: ssa.TypeI32}, 144 {Index: 13, Kind: ABIArgKindReg, Reg: v6VReg, Type: ssa.TypeF32}, 145 {Index: 14, Kind: ABIArgKindReg, Reg: x7VReg, Type: ssa.TypeI64}, 146 {Index: 15, Kind: ABIArgKindReg, Reg: v7VReg, Type: ssa.TypeF64}, 147 {Index: 16, Kind: ABIArgKindStack, Type: ssa.TypeI32, Offset: 0}, 148 {Index: 17, Kind: ABIArgKindStack, Type: ssa.TypeF32, Offset: 8}, 149 {Index: 18, Kind: ABIArgKindStack, Type: ssa.TypeI64, Offset: 16}, 150 {Index: 19, Kind: ABIArgKindStack, Type: ssa.TypeF64, Offset: 24}, 151 {Index: 20, Kind: ABIArgKindStack, Type: ssa.TypeI32, Offset: 32}, 152 {Index: 21, Kind: ABIArgKindStack, Type: ssa.TypeF32, Offset: 40}, 153 {Index: 22, Kind: ABIArgKindStack, Type: ssa.TypeI64, Offset: 48}, 154 {Index: 23, Kind: ABIArgKindStack, Type: ssa.TypeF64, Offset: 56}, 155 {Index: 24, Kind: ABIArgKindStack, Type: ssa.TypeI32, Offset: 64}, 156 {Index: 25, Kind: ABIArgKindStack, Type: ssa.TypeF32, Offset: 72}, 157 {Index: 26, Kind: ABIArgKindStack, Type: ssa.TypeI64, Offset: 80}, 158 {Index: 27, Kind: ABIArgKindStack, Type: ssa.TypeF64, Offset: 88}, 159 {Index: 28, Kind: ABIArgKindStack, Type: ssa.TypeI32, Offset: 96}, 160 {Index: 29, Kind: ABIArgKindStack, Type: ssa.TypeF32, Offset: 104}, 161 {Index: 30, Kind: ABIArgKindStack, Type: ssa.TypeI64, Offset: 112}, 162 {Index: 31, Kind: ABIArgKindStack, Type: ssa.TypeF64, Offset: 120}, 163 }, 164 Rets: []ABIArg{ 165 {Index: 0, Kind: ABIArgKindReg, Reg: x0VReg, Type: ssa.TypeI32}, 166 {Index: 1, Kind: ABIArgKindReg, Reg: v0VReg, Type: ssa.TypeF32}, 167 {Index: 2, Kind: ABIArgKindReg, Reg: x1VReg, Type: ssa.TypeI64}, 168 {Index: 3, Kind: ABIArgKindReg, Reg: v1VReg, Type: ssa.TypeF64}, 169 {Index: 4, Kind: ABIArgKindReg, Reg: x2VReg, Type: ssa.TypeI32}, 170 {Index: 5, Kind: ABIArgKindReg, Reg: v2VReg, Type: ssa.TypeF32}, 171 {Index: 6, Kind: ABIArgKindReg, Reg: x3VReg, Type: ssa.TypeI64}, 172 {Index: 7, Kind: ABIArgKindReg, Reg: v3VReg, Type: ssa.TypeF64}, 173 {Index: 8, Kind: ABIArgKindReg, Reg: x4VReg, Type: ssa.TypeI32}, 174 {Index: 9, Kind: ABIArgKindReg, Reg: v4VReg, Type: ssa.TypeF32}, 175 {Index: 10, Kind: ABIArgKindReg, Reg: x5VReg, Type: ssa.TypeI64}, 176 {Index: 11, Kind: ABIArgKindReg, Reg: v5VReg, Type: ssa.TypeF64}, 177 {Index: 12, Kind: ABIArgKindReg, Reg: x6VReg, Type: ssa.TypeI32}, 178 {Index: 13, Kind: ABIArgKindReg, Reg: v6VReg, Type: ssa.TypeF32}, 179 {Index: 14, Kind: ABIArgKindReg, Reg: x7VReg, Type: ssa.TypeI64}, 180 {Index: 15, Kind: ABIArgKindReg, Reg: v7VReg, Type: ssa.TypeF64}, 181 {Index: 16, Kind: ABIArgKindStack, Type: ssa.TypeI32, Offset: 0}, 182 {Index: 17, Kind: ABIArgKindStack, Type: ssa.TypeF32, Offset: 8}, 183 {Index: 18, Kind: ABIArgKindStack, Type: ssa.TypeI64, Offset: 16}, 184 {Index: 19, Kind: ABIArgKindStack, Type: ssa.TypeF64, Offset: 24}, 185 {Index: 20, Kind: ABIArgKindStack, Type: ssa.TypeI32, Offset: 32}, 186 {Index: 21, Kind: ABIArgKindStack, Type: ssa.TypeF32, Offset: 40}, 187 {Index: 22, Kind: ABIArgKindStack, Type: ssa.TypeI64, Offset: 48}, 188 {Index: 23, Kind: ABIArgKindStack, Type: ssa.TypeF64, Offset: 56}, 189 {Index: 24, Kind: ABIArgKindStack, Type: ssa.TypeI32, Offset: 64}, 190 {Index: 25, Kind: ABIArgKindStack, Type: ssa.TypeF32, Offset: 72}, 191 {Index: 26, Kind: ABIArgKindStack, Type: ssa.TypeI64, Offset: 80}, 192 {Index: 27, Kind: ABIArgKindStack, Type: ssa.TypeF64, Offset: 88}, 193 {Index: 28, Kind: ABIArgKindStack, Type: ssa.TypeI32, Offset: 96}, 194 {Index: 29, Kind: ABIArgKindStack, Type: ssa.TypeF32, Offset: 104}, 195 {Index: 30, Kind: ABIArgKindStack, Type: ssa.TypeI64, Offset: 112}, 196 {Index: 31, Kind: ABIArgKindStack, Type: ssa.TypeF64, Offset: 120}, 197 }, 198 ArgIntRealRegs: 8, ArgFloatRealRegs: 8, 199 RetIntRealRegs: 8, RetFloatRealRegs: 8, 200 }, 201 }, 202 { 203 name: "all regs", 204 sig: &ssa.Signature{ 205 Params: []ssa.Type{ 206 ssa.TypeI32, ssa.TypeF32, 207 ssa.TypeI64, ssa.TypeF64, 208 ssa.TypeI32, ssa.TypeF32, 209 ssa.TypeI64, ssa.TypeF64, 210 ssa.TypeI32, ssa.TypeF32, 211 ssa.TypeI64, ssa.TypeF64, 212 ssa.TypeI32, ssa.TypeF32, 213 ssa.TypeI64, ssa.TypeF64, 214 }, 215 Results: []ssa.Type{ 216 ssa.TypeI32, ssa.TypeF32, 217 ssa.TypeI64, ssa.TypeF64, 218 ssa.TypeI32, ssa.TypeF32, 219 ssa.TypeI64, ssa.TypeF64, 220 ssa.TypeI32, ssa.TypeF32, 221 ssa.TypeI64, ssa.TypeF64, 222 ssa.TypeI32, ssa.TypeF32, 223 ssa.TypeI64, ssa.TypeF64, 224 }, 225 }, 226 exp: FunctionABI{ 227 Args: []ABIArg{ 228 {Index: 0, Kind: ABIArgKindReg, Reg: x0VReg, Type: ssa.TypeI32}, 229 {Index: 1, Kind: ABIArgKindReg, Reg: v0VReg, Type: ssa.TypeF32}, 230 {Index: 2, Kind: ABIArgKindReg, Reg: x1VReg, Type: ssa.TypeI64}, 231 {Index: 3, Kind: ABIArgKindReg, Reg: v1VReg, Type: ssa.TypeF64}, 232 {Index: 4, Kind: ABIArgKindReg, Reg: x2VReg, Type: ssa.TypeI32}, 233 {Index: 5, Kind: ABIArgKindReg, Reg: v2VReg, Type: ssa.TypeF32}, 234 {Index: 6, Kind: ABIArgKindReg, Reg: x3VReg, Type: ssa.TypeI64}, 235 {Index: 7, Kind: ABIArgKindReg, Reg: v3VReg, Type: ssa.TypeF64}, 236 {Index: 8, Kind: ABIArgKindReg, Reg: x4VReg, Type: ssa.TypeI32}, 237 {Index: 9, Kind: ABIArgKindReg, Reg: v4VReg, Type: ssa.TypeF32}, 238 {Index: 10, Kind: ABIArgKindReg, Reg: x5VReg, Type: ssa.TypeI64}, 239 {Index: 11, Kind: ABIArgKindReg, Reg: v5VReg, Type: ssa.TypeF64}, 240 {Index: 12, Kind: ABIArgKindReg, Reg: x6VReg, Type: ssa.TypeI32}, 241 {Index: 13, Kind: ABIArgKindReg, Reg: v6VReg, Type: ssa.TypeF32}, 242 {Index: 14, Kind: ABIArgKindReg, Reg: x7VReg, Type: ssa.TypeI64}, 243 {Index: 15, Kind: ABIArgKindReg, Reg: v7VReg, Type: ssa.TypeF64}, 244 }, 245 Rets: []ABIArg{ 246 {Index: 0, Kind: ABIArgKindReg, Reg: x0VReg, Type: ssa.TypeI32}, 247 {Index: 1, Kind: ABIArgKindReg, Reg: v0VReg, Type: ssa.TypeF32}, 248 {Index: 2, Kind: ABIArgKindReg, Reg: x1VReg, Type: ssa.TypeI64}, 249 {Index: 3, Kind: ABIArgKindReg, Reg: v1VReg, Type: ssa.TypeF64}, 250 {Index: 4, Kind: ABIArgKindReg, Reg: x2VReg, Type: ssa.TypeI32}, 251 {Index: 5, Kind: ABIArgKindReg, Reg: v2VReg, Type: ssa.TypeF32}, 252 {Index: 6, Kind: ABIArgKindReg, Reg: x3VReg, Type: ssa.TypeI64}, 253 {Index: 7, Kind: ABIArgKindReg, Reg: v3VReg, Type: ssa.TypeF64}, 254 {Index: 8, Kind: ABIArgKindReg, Reg: x4VReg, Type: ssa.TypeI32}, 255 {Index: 9, Kind: ABIArgKindReg, Reg: v4VReg, Type: ssa.TypeF32}, 256 {Index: 10, Kind: ABIArgKindReg, Reg: x5VReg, Type: ssa.TypeI64}, 257 {Index: 11, Kind: ABIArgKindReg, Reg: v5VReg, Type: ssa.TypeF64}, 258 {Index: 12, Kind: ABIArgKindReg, Reg: x6VReg, Type: ssa.TypeI32}, 259 {Index: 13, Kind: ABIArgKindReg, Reg: v6VReg, Type: ssa.TypeF32}, 260 {Index: 14, Kind: ABIArgKindReg, Reg: x7VReg, Type: ssa.TypeI64}, 261 {Index: 15, Kind: ABIArgKindReg, Reg: v7VReg, Type: ssa.TypeF64}, 262 }, 263 ArgIntRealRegs: 8, ArgFloatRealRegs: 8, 264 RetIntRealRegs: 8, RetFloatRealRegs: 8, 265 }, 266 }, 267 } { 268 tc := tc 269 t.Run(tc.name, func(t *testing.T) { 270 abi := FunctionABI{} 271 abi.Init(tc.sig, intParamResultRegs, floatParamResultRegs) 272 require.Equal(t, tc.exp.Args, abi.Args) 273 require.Equal(t, tc.exp.Rets, abi.Rets) 274 require.Equal(t, tc.exp.ArgStackSize, abi.ArgStackSize) 275 require.Equal(t, tc.exp.RetStackSize, abi.RetStackSize) 276 require.Equal(t, tc.exp.RetIntRealRegs, abi.RetIntRealRegs) 277 require.Equal(t, tc.exp.RetFloatRealRegs, abi.RetFloatRealRegs) 278 require.Equal(t, tc.exp.ArgIntRealRegs, abi.ArgIntRealRegs) 279 require.Equal(t, tc.exp.ArgFloatRealRegs, abi.ArgFloatRealRegs) 280 }) 281 } 282 }