github.com/cloudwego/frugal@v0.1.15/internal/binary/decoder/translator.go (about) 1 /* 2 * Copyright 2022 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package decoder 18 19 import ( 20 `fmt` 21 `reflect` 22 23 `github.com/cloudwego/frugal/internal/atm/hir` 24 `github.com/cloudwego/frugal/internal/binary/defs` 25 `github.com/cloudwego/frugal/internal/rt` 26 ) 27 28 /** Function Prototype 29 * 30 * func(buf unsafe.Pointer, nb int, i int, p unsafe.Pointer, rs *RuntimeState, st int) (pos int, err error) 31 */ 32 33 const ( 34 ARG_buf = 0 35 ARG_nb = 1 36 ARG_i = 2 37 ARG_p = 3 38 ARG_rs = 4 39 ARG_st = 5 40 ) 41 42 /** Register Allocations 43 * 44 * P1 Current Working Pointer 45 * P2 Input Buffer Pointer 46 * P3 Runtime State Pointer 47 * P4 Error Type Pointer 48 * P5 Error Value Pointer 49 * 50 * R2 Input Cursor 51 * R3 State Index 52 * R4 Field Tag 53 */ 54 55 const ( 56 WP = hir.P1 57 IP = hir.P2 58 RS = hir.P3 59 ET = hir.P4 // may also be used as a temporary pointer register 60 EP = hir.P5 // may also be used as a temporary pointer register 61 ) 62 63 const ( 64 IC = hir.R2 65 ST = hir.R3 66 TG = hir.R4 67 ) 68 69 const ( 70 TP = hir.P0 71 TR = hir.R0 72 UR = hir.R1 73 ) 74 75 const ( 76 LB_eof = "_eof" 77 LB_halt = "_halt" 78 LB_type = "_type" 79 LB_skip = "_skip" 80 LB_error = "_error" 81 LB_missing = "_missing" 82 LB_overflow = "_overflow" 83 ) 84 85 var ( 86 _T_byte *rt.GoType 87 _E_overflow error 88 _V_zerovalue uint64 89 ) 90 91 func init() { 92 _T_byte = rt.UnpackType(reflect.TypeOf(byte(0))) 93 _E_overflow = fmt.Errorf("frugal: decoder stack overflow") 94 } 95 96 func Translate(s Program) hir.Program { 97 p := hir.CreateBuilder() 98 prologue (p) 99 program (p, s) 100 epilogue (p) 101 errors (p) 102 return p.Build() 103 } 104 105 func errors(p *hir.Builder) { 106 p.Label (LB_eof) 107 p.LDAQ (ARG_nb, UR) 108 p.SUB (TR, UR, TR) 109 p.GCALL (F_error_eof). 110 A0 (TR). 111 R0 (ET). 112 R1 (EP) 113 p.JMP (LB_error) 114 p.Label (LB_type) 115 p.GCALL (F_error_type). 116 A0 (UR). 117 A1 (TR). 118 R0 (ET). 119 R1 (EP) 120 p.JMP (LB_error) 121 p.Label (LB_skip) 122 p.GCALL (F_error_skip). 123 A0 (TR). 124 R0 (ET). 125 R1 (EP) 126 p.JMP (LB_error) 127 p.Label (LB_missing) 128 p.GCALL (F_error_missing). 129 A0 (ET). 130 A1 (UR). 131 A2 (TR). 132 R0 (ET). 133 R1 (EP) 134 p.JMP (LB_error) 135 p.Label (LB_overflow) 136 p.IP (&_E_overflow, TP) 137 p.LP (TP, 0, ET) 138 p.LP (TP, 8, EP) 139 p.JMP (LB_error) 140 } 141 142 func program(p *hir.Builder, s Program) { 143 for i, v := range s { 144 p.Mark(i) 145 translators[v.Op](p, v) 146 } 147 } 148 149 func prologue(p *hir.Builder) { 150 p.LDAP (ARG_buf, IP) 151 p.LDAQ (ARG_i, IC) 152 p.LDAP (ARG_p, WP) 153 p.LDAP (ARG_rs, RS) 154 p.LDAQ (ARG_st, ST) 155 p.MOV (hir.Rz, TR) 156 p.MOV (hir.Rz, UR) 157 } 158 159 func epilogue(p *hir.Builder) { 160 p.Label (LB_halt) 161 p.MOVP (hir.Pn, ET) 162 p.MOVP (hir.Pn, EP) 163 p.Label (LB_error) 164 p.RET (). 165 R0 (IC). 166 R1 (ET). 167 R2 (EP) 168 } 169 170 var translators = [256]func(*hir.Builder, Instr) { 171 OP_int : translate_OP_int, 172 OP_str : translate_OP_str, 173 OP_str_nocopy : translate_OP_str_nocopy, 174 OP_bin : translate_OP_bin, 175 OP_bin_nocopy : translate_OP_bin_nocopy, 176 OP_enum : translate_OP_enum, 177 OP_size : translate_OP_size, 178 OP_type : translate_OP_type, 179 OP_seek : translate_OP_seek, 180 OP_deref : translate_OP_deref, 181 OP_ctr_load : translate_OP_ctr_load, 182 OP_ctr_decr : translate_OP_ctr_decr, 183 OP_ctr_is_zero : translate_OP_ctr_is_zero, 184 OP_map_alloc : translate_OP_map_alloc, 185 OP_map_close : translate_OP_map_close, 186 OP_map_set_i8 : translate_OP_map_set_i8, 187 OP_map_set_i16 : translate_OP_map_set_i16, 188 OP_map_set_i32 : translate_OP_map_set_i32, 189 OP_map_set_i64 : translate_OP_map_set_i64, 190 OP_map_set_str : translate_OP_map_set_str, 191 OP_map_set_enum : translate_OP_map_set_enum, 192 OP_map_set_pointer : translate_OP_map_set_pointer, 193 OP_list_alloc : translate_OP_list_alloc, 194 OP_struct_skip : translate_OP_struct_skip, 195 OP_struct_ignore : translate_OP_struct_ignore, 196 OP_struct_bitmap : translate_OP_struct_bitmap, 197 OP_struct_switch : translate_OP_struct_switch, 198 OP_struct_require : translate_OP_struct_require, 199 OP_struct_is_stop : translate_OP_struct_is_stop, 200 OP_struct_mark_tag : translate_OP_struct_mark_tag, 201 OP_struct_read_type : translate_OP_struct_read_type, 202 OP_struct_check_type : translate_OP_struct_check_type, 203 OP_make_state : translate_OP_make_state, 204 OP_drop_state : translate_OP_drop_state, 205 OP_construct : translate_OP_construct, 206 OP_initialize : translate_OP_initialize, 207 OP_defer : translate_OP_defer, 208 OP_goto : translate_OP_goto, 209 OP_halt : translate_OP_halt, 210 } 211 212 func translate_OP_int(p *hir.Builder, v Instr) { 213 switch v.Iv { 214 case 1 : p.ADDP(IP, IC, EP); p.LB(EP, 0, TR); p.SB(TR, WP, 0); p.ADDI(IC, 1, IC) 215 case 2 : p.ADDP(IP, IC, EP); p.LW(EP, 0, TR); p.SWAPW(TR, TR); p.SW(TR, WP, 0); p.ADDI(IC, 2, IC) 216 case 4 : p.ADDP(IP, IC, EP); p.LL(EP, 0, TR); p.SWAPL(TR, TR); p.SL(TR, WP, 0); p.ADDI(IC, 4, IC) 217 case 8 : p.ADDP(IP, IC, EP); p.LQ(EP, 0, TR); p.SWAPQ(TR, TR); p.SQ(TR, WP, 0); p.ADDI(IC, 8, IC) 218 default : panic("can only convert 1, 2, 4 or 8 bytes at a time") 219 } 220 } 221 222 func translate_OP_str(p *hir.Builder, _ Instr) { 223 p.SP (hir.Pn, WP, 0) 224 p.ADDP (IP, IC, EP) 225 p.ADDI (IC, 4, IC) 226 p.LL (EP, 0, TR) 227 p.SWAPL (TR, TR) 228 p.LDAQ (ARG_nb, UR) 229 p.BLTU (UR, TR, LB_eof) 230 p.BEQ (TR, hir.Rz, "_empty_{n}") 231 p.ADDPI (EP, 4, EP) 232 p.ADD (IC, TR, IC) 233 p.GCALL (F_slicebytetostring). 234 A0 (hir.Pn). 235 A1 (EP). 236 A2 (TR). 237 R0 (TP). 238 R1 (TR) 239 p.SP (TP, WP, 0) 240 p.Label ("_empty_{n}") 241 p.SQ (TR, WP, 8) 242 } 243 244 func translate_OP_str_nocopy(p *hir.Builder, _ Instr) { 245 p.SP (hir.Pn, WP, 0) 246 translate_OP_binstr_nocopy(p) 247 } 248 249 func translate_OP_bin(p *hir.Builder, _ Instr) { 250 p.IP (&_V_zerovalue, TP) 251 p.SP (TP, WP, 0) 252 p.ADDP (IP, IC, EP) 253 p.ADDI (IC, 4, IC) 254 p.LL (EP, 0, TR) 255 p.SWAPL (TR, TR) 256 p.LDAQ (ARG_nb, UR) 257 p.BLTU (UR, TR, LB_eof) 258 p.BEQ (TR, hir.Rz, "_empty_{n}") 259 p.ADDPI (EP, 4, EP) 260 p.ADD (IC, TR, IC) 261 p.IP (_T_byte, TP) 262 p.GCALL (F_mallocgc). 263 A0 (TR). 264 A1 (TP). 265 A2 (hir.Rz). 266 R0 (TP) 267 p.BCOPY (EP, TR, TP) 268 p.SP (TP, WP, 0) 269 p.Label ("_empty_{n}") 270 p.SQ (TR, WP, 8) 271 p.SQ (TR, WP, 16) 272 } 273 274 func translate_OP_bin_nocopy(p *hir.Builder, _ Instr) { 275 p.IP (&_V_zerovalue, TP) 276 p.SP (TP, WP, 0) 277 translate_OP_binstr_nocopy(p) 278 p.SQ (TR, WP, 16) 279 } 280 281 func translate_OP_binstr_nocopy(p *hir.Builder) { 282 p.ADDP (IP, IC, EP) 283 p.ADDI (IC, 4, IC) 284 p.LL (EP, 0, TR) 285 p.SWAPL (TR, TR) 286 p.LDAQ (ARG_nb, UR) 287 p.BLTU (UR, TR, LB_eof) 288 p.BEQ (TR, hir.Rz, "_empty_{n}") 289 p.ADDPI (EP, 4, EP) 290 p.ADD (IC, TR, IC) 291 p.SP (EP, WP, 0) 292 p.Label ("_empty_{n}") 293 p.SQ (TR, WP, 8) 294 } 295 296 func translate_OP_enum(p *hir.Builder, _ Instr) { 297 p.ADDP (IP, IC, EP) 298 p.LL (EP, 0, TR) 299 p.SWAPL (TR, TR) 300 p.SXLQ (TR, TR) 301 p.SQ (TR, WP, 0) 302 p.ADDI (IC, 4, IC) 303 } 304 305 func translate_OP_size(p *hir.Builder, v Instr) { 306 p.IQ (v.Iv, TR) 307 p.LDAQ (ARG_nb, UR) 308 p.BLTU (UR, TR, LB_eof) 309 } 310 311 func translate_OP_type(p *hir.Builder, v Instr) { 312 p.ADDP (IP, IC, TP) 313 p.LB (TP, 0, TR) 314 p.IB (int8(v.Tx), UR) 315 p.BNE (TR, UR, LB_type) 316 p.ADDI (IC, 1, IC) 317 } 318 319 func translate_OP_seek(p *hir.Builder, v Instr) { 320 p.ADDPI (WP, v.Iv, WP) 321 } 322 323 func translate_OP_deref(p *hir.Builder, v Instr) { 324 p.LQ (WP, 0, TR) 325 p.BNE (TR, hir.Rz, "_skip_{n}") 326 p.IB (1, UR) 327 p.IP (v.Vt, TP) 328 p.IQ (int64(v.Vt.Size), TR) 329 p.GCALL (F_mallocgc). 330 A0 (TR). 331 A1 (TP). 332 A2 (UR). 333 R0 (TP) 334 p.SP (TP, WP, 0) 335 p.Label ("_skip_{n}") 336 p.LP (WP, 0, WP) 337 } 338 339 func translate_OP_ctr_load(p *hir.Builder, _ Instr) { 340 p.ADDP (IP, IC, EP) 341 p.ADDI (IC, 4, IC) 342 p.LL (EP, 0, TR) 343 p.SWAPL (TR, TR) 344 p.ADDP (RS, ST, TP) 345 p.SQ (TR, TP, NbOffset) 346 } 347 348 func translate_OP_ctr_decr(p *hir.Builder, _ Instr) { 349 p.ADDP (RS, ST, TP) 350 p.LQ (TP, NbOffset, TR) 351 p.SUBI (TR, 1, TR) 352 p.SQ (TR, TP, NbOffset) 353 } 354 355 func translate_OP_ctr_is_zero(p *hir.Builder, v Instr) { 356 p.ADDP (RS, ST, TP) 357 p.LQ (TP, NbOffset, TR) 358 p.BEQ (TR, hir.Rz, p.At(v.To)) 359 } 360 361 func translate_OP_map_alloc(p *hir.Builder, v Instr) { 362 p.ADDP (RS, ST, TP) 363 p.LQ (TP, NbOffset, TR) 364 p.IP (v.Vt, ET) 365 p.GCALL (F_makemap). 366 A0 (ET). 367 A1 (TR). 368 A2 (hir.Pn). 369 R0 (TP) 370 p.SP (TP, WP, 0) 371 p.ADDP (RS, ST, EP) 372 p.SP (TP, EP, MpOffset) 373 } 374 375 func translate_OP_map_close(p *hir.Builder, _ Instr) { 376 p.ADDP (RS, ST, TP) 377 p.SP (hir.Pn, TP, MpOffset) 378 } 379 380 func translate_OP_map_set_i8(p *hir.Builder, v Instr) { 381 p.ADDP (IP, IC, EP) 382 p.ADDP (RS, ST, TP) 383 p.LP (TP, MpOffset, TP) 384 p.IP (v.Vt, ET) 385 p.GCALL (F_mapassign). 386 A0 (ET). 387 A1 (TP). 388 A2 (EP). 389 R0 (WP) 390 p.ADDI (IC, 1, IC) 391 } 392 393 func translate_OP_map_set_i16(p *hir.Builder, v Instr) { 394 p.ADDP (IP, IC, ET) 395 p.ADDI (IC, 2, IC) 396 p.ADDP (RS, ST, TP) 397 p.LP (TP, MpOffset, EP) 398 p.LW (ET, 0, TR) 399 p.SWAPW (TR, TR) 400 p.SW (TR, RS, IvOffset) 401 p.ADDPI (RS, IvOffset, TP) 402 p.IP (v.Vt, ET) 403 p.GCALL (F_mapassign). 404 A0 (ET). 405 A1 (EP). 406 A2 (TP). 407 R0 (WP) 408 } 409 410 func translate_OP_map_set_i32(p *hir.Builder, v Instr) { 411 if rt.MapType(v.Vt).IsFastMap() { 412 translate_OP_map_set_i32_fast(p, v) 413 } else { 414 translate_OP_map_set_i32_safe(p, v) 415 } 416 } 417 418 func translate_OP_map_set_i32_fast(p *hir.Builder, v Instr) { 419 p.ADDP (IP, IC, EP) 420 p.ADDI (IC, 4, IC) 421 p.ADDP (RS, ST, TP) 422 p.LP (TP, MpOffset, TP) 423 p.LL (EP, 0, TR) 424 p.SWAPL (TR, TR) 425 p.IP (v.Vt, ET) 426 p.GCALL (F_mapassign_fast32). 427 A0 (ET). 428 A1 (TP). 429 A2 (TR). 430 R0 (WP) 431 } 432 433 func translate_OP_map_set_i32_safe(p *hir.Builder, v Instr) { 434 p.ADDP (IP, IC, ET) 435 p.ADDI (IC, 4, IC) 436 p.ADDP (RS, ST, TP) 437 p.LP (TP, MpOffset, EP) 438 p.LL (ET, 0, TR) 439 p.SWAPL (TR, TR) 440 p.SL (TR, RS, IvOffset) 441 p.ADDPI (RS, IvOffset, TP) 442 p.IP (v.Vt, ET) 443 p.GCALL (F_mapassign). 444 A0 (ET). 445 A1 (EP). 446 A2 (TP). 447 R0 (WP) 448 } 449 450 func translate_OP_map_set_i64(p *hir.Builder, v Instr) { 451 if rt.MapType(v.Vt).IsFastMap() { 452 translate_OP_map_set_i64_fast(p, v) 453 } else { 454 translate_OP_map_set_i64_safe(p, v) 455 } 456 } 457 458 func translate_OP_map_set_i64_fast(p *hir.Builder, v Instr) { 459 p.ADDP (IP, IC, EP) 460 p.ADDI (IC, 8, IC) 461 p.ADDP (RS, ST, TP) 462 p.LP (TP, MpOffset, TP) 463 p.LQ (EP, 0, TR) 464 p.SWAPQ (TR, TR) 465 p.IP (v.Vt, ET) 466 p.GCALL (F_mapassign_fast64). 467 A0 (ET). 468 A1 (TP). 469 A2 (TR). 470 R0 (WP) 471 } 472 473 func translate_OP_map_set_i64_safe(p *hir.Builder, v Instr) { 474 p.ADDP (IP, IC, ET) 475 p.ADDI (IC, 2, IC) 476 p.ADDP (RS, ST, TP) 477 p.LP (TP, MpOffset, EP) 478 p.LQ (ET, 0, TR) 479 p.SWAPQ (TR, TR) 480 p.SQ (TR, RS, IvOffset) 481 p.ADDPI (RS, IvOffset, TP) 482 p.IP (v.Vt, ET) 483 p.GCALL (F_mapassign). 484 A0 (ET). 485 A1 (EP). 486 A2 (TP). 487 R0 (WP) 488 } 489 490 func translate_OP_map_set_str(p *hir.Builder, v Instr) { 491 if rt.MapType(v.Vt).IsFastMap() { 492 translate_OP_map_set_str_fast(p, v) 493 } else { 494 translate_OP_map_set_str_safe(p, v) 495 } 496 } 497 498 func translate_OP_map_set_str_fast(p *hir.Builder, v Instr) { 499 p.ADDP (IP, IC, EP) 500 p.ADDI (IC, 4, IC) 501 p.LL (EP, 0, TR) 502 p.SWAPL (TR, TR) 503 p.LDAQ (ARG_nb, UR) 504 p.BLTU (UR, TR, LB_eof) 505 p.MOVP (hir.Pn, EP) 506 p.BEQ (TR, hir.Rz, "_empty_{n}") 507 p.ADDP (IP, IC, ET) 508 p.ADD (IC, TR, IC) 509 p.GCALL (F_slicebytetostring). 510 A0 (hir.Pn). 511 A1 (ET). 512 A2 (TR). 513 R0 (EP). 514 R1 (TR) 515 p.Label ("_empty_{n}") 516 p.ADDP (RS, ST, TP) 517 p.LP (TP, MpOffset, TP) 518 p.IP (v.Vt, ET) 519 p.GCALL (F_mapassign_faststr). 520 A0 (ET). 521 A1 (TP). 522 A2 (EP). 523 A3 (TR). 524 R0 (WP) 525 } 526 527 func translate_OP_map_set_str_safe(p *hir.Builder, v Instr) { 528 p.ADDP (IP, IC, ET) 529 p.ADDI (IC, 4, IC) 530 p.LL (ET, 0, TR) 531 p.SWAPL (TR, TR) 532 p.LDAQ (ARG_nb, UR) 533 p.BLTU (UR, TR, LB_eof) 534 p.SQ (TR, RS, IvOffset) 535 p.SP (hir.Pn, RS, PrOffset) 536 p.BEQ (TR, hir.Rz, "_empty_{n}") 537 p.ADDPI (ET, 4, ET) 538 p.ADD (IC, TR, IC) 539 p.GCALL (F_slicebytetostring). 540 A0 (hir.Pn). 541 A1 (ET). 542 A2 (TR). 543 R0 (TP). 544 R1 (TR) 545 p.SP (TP, RS, PrOffset) 546 p.Label ("_empty_{n}") 547 p.ADDP (RS, ST, EP) 548 p.LP (EP, MpOffset, EP) 549 p.IP (v.Vt, ET) 550 p.ADDPI (RS, PrOffset, TP) 551 p.GCALL (F_mapassign). 552 A0 (ET). 553 A1 (EP). 554 A2 (TP). 555 R0 (WP) 556 p.SP (hir.Pn, RS, PrOffset) 557 } 558 559 func translate_OP_map_set_enum(p *hir.Builder, v Instr) { 560 if rt.MapType(v.Vt).IsFastMap() { 561 translate_OP_map_set_enum_fast(p, v) 562 } else { 563 translate_OP_map_set_enum_safe(p, v) 564 } 565 } 566 567 func translate_OP_map_set_enum_fast(p *hir.Builder, v Instr) { 568 p.ADDP (IP, IC, EP) 569 p.ADDI (IC, 4, IC) 570 p.ADDP (RS, ST, TP) 571 p.LP (TP, MpOffset, TP) 572 p.LL (EP, 0, TR) 573 p.SWAPL (TR, TR) 574 p.SXLQ (TR, TR) 575 p.IP (v.Vt, ET) 576 p.GCALL (F_mapassign_fast64). 577 A0 (ET). 578 A1 (TP). 579 A2 (TR). 580 R0 (WP) 581 } 582 583 func translate_OP_map_set_enum_safe(p *hir.Builder, v Instr) { 584 p.ADDP (IP, IC, ET) 585 p.ADDI (IC, 4, IC) 586 p.ADDP (RS, ST, TP) 587 p.LP (TP, MpOffset, EP) 588 p.LL (ET, 0, TR) 589 p.SWAPL (TR, TR) 590 p.SXLQ (TR, TR) 591 p.SQ (TR, RS, IvOffset) 592 p.ADDPI (RS, IvOffset, TP) 593 p.IP (v.Vt, ET) 594 p.GCALL (F_mapassign). 595 A0 (ET). 596 A1 (EP). 597 A2 (TP). 598 R0 (WP) 599 } 600 601 func translate_OP_map_set_pointer(p *hir.Builder, v Instr) { 602 if rt.MapType(v.Vt).IsFastMap() { 603 translate_OP_map_set_pointer_fast(p, v) 604 } else { 605 translate_OP_map_set_pointer_safe(p, v) 606 } 607 } 608 609 func translate_OP_map_set_pointer_fast(p *hir.Builder, v Instr) { 610 p.ADDP (RS, ST, TP) 611 p.LP (TP, MpOffset, TP) 612 p.IP (v.Vt, ET) 613 p.GCALL (F_mapassign_fast64ptr). 614 A0 (ET). 615 A1 (TP). 616 A2 (WP). 617 R0 (WP) 618 } 619 620 func translate_OP_map_set_pointer_safe(p *hir.Builder, v Instr) { 621 p.ADDP (RS, ST, TP) 622 p.LP (TP, MpOffset, EP) 623 p.SP (WP, RS, PrOffset) 624 p.IP (v.Vt, ET) 625 p.ADDPI (RS, PrOffset, TP) 626 p.GCALL (F_mapassign). 627 A0 (ET). 628 A1 (EP). 629 A2 (TP). 630 R0 (WP) 631 p.SP (hir.Pn, RS, PrOffset) 632 } 633 634 func translate_OP_list_alloc(p *hir.Builder, v Instr) { 635 p.ADDP (RS, ST, TP) 636 p.LQ (TP, NbOffset, TR) 637 p.SQ (TR, WP, 8) 638 p.LQ (WP, 16, UR) 639 p.BNE (TR, hir.Rz, "_alloc_{n}") 640 p.BNE (UR, hir.Rz, "_done_{n}") 641 p.IP (&_V_zerovalue, TP) 642 p.SP (TP, WP, 0) 643 p.SQ (hir.Rz, WP, 16) 644 p.JMP ("_done_{n}") 645 p.Label ("_alloc_{n}") 646 p.BGEU (UR, TR, "_done_{n}") 647 p.SQ (TR, WP, 16) 648 p.IB (1, UR) 649 p.IP (v.Vt, TP) 650 p.MULI (TR, int64(v.Vt.Size), TR) 651 p.GCALL (F_mallocgc). 652 A0 (TR). 653 A1 (TP). 654 A2 (UR). 655 R0 (TP) 656 p.SP (TP, WP, 0) 657 p.Label ("_done_{n}") 658 p.LP (WP, 0, WP) 659 } 660 661 func translate_OP_struct_skip(p *hir.Builder, _ Instr) { 662 p.ADDPI (RS, SkOffset, TP) 663 p.LDAQ (ARG_nb, TR) 664 p.SUB (TR, IC, TR) 665 p.ADDP (IP, IC, EP) 666 p.CCALL (C_skip). 667 A0 (TP). 668 A1 (EP). 669 A2 (TR). 670 A3 (TG). 671 R0 (TR) 672 p.BLT (TR, hir.Rz, LB_skip) 673 p.ADD (IC, TR, IC) 674 } 675 676 func translate_OP_struct_ignore(p *hir.Builder, _ Instr) { 677 p.ADDPI (RS, SkOffset, TP) 678 p.LDAQ (ARG_nb, TR) 679 p.SUB (TR, IC, TR) 680 p.ADDP (IP, IC, EP) 681 p.IB (int8(defs.T_struct), TG) 682 p.CCALL (C_skip). 683 A0 (TP). 684 A1 (EP). 685 A2 (TR). 686 A3 (TG). 687 R0 (TR) 688 p.BLT (TR, hir.Rz, LB_skip) 689 p.ADD (IC, TR, IC) 690 } 691 692 func translate_OP_struct_bitmap(p *hir.Builder, v Instr) { 693 buf := newFieldBitmap() 694 buf.Clear() 695 696 /* add all the bits */ 697 for _, i := range v.IntSeq() { 698 buf.Append(i) 699 } 700 701 /* allocate a new bitmap */ 702 p.GCALL (F_newFieldBitmap).R0(TP) 703 p.ADDP (RS, ST, EP) 704 p.SP (TP, EP, FmOffset) 705 706 /* clear bits of required fields if any */ 707 for i := int64(0); i < MaxBitmap; i++ { 708 if buf[i] != 0 { 709 p.SQ(hir.Rz, TP, i * 8) 710 } 711 } 712 713 /* release the buffer */ 714 buf.Clear() 715 buf.Free() 716 } 717 718 func translate_OP_struct_switch(p *hir.Builder, v Instr) { 719 stab := v.IntSeq() 720 ptab := make([]string, v.Iv) 721 722 /* convert the switch table */ 723 for i, to := range stab { 724 if to >= 0 { 725 ptab[i] = p.At(to) 726 } 727 } 728 729 /* load and dispatch the field */ 730 p.ADDP (IP, IC, EP) 731 p.ADDI (IC, 2, IC) 732 p.LW (EP, 0, TR) 733 p.SWAPW (TR, TR) 734 p.BSW (TR, ptab) 735 } 736 737 func translate_OP_struct_require(p *hir.Builder, v Instr) { 738 buf := newFieldBitmap() 739 buf.Clear() 740 741 /* add all the bits */ 742 for _, i := range v.IntSeq() { 743 buf.Append(i) 744 } 745 746 /* load the bitmap */ 747 p.ADDP (RS, ST, EP) 748 p.LP (EP, FmOffset, TP) 749 750 /* test mask for each word if any */ 751 for i := int64(0); i < MaxBitmap; i++ { 752 if buf[i] != 0 { 753 p.LQ (TP, i * 8, TR) 754 p.ANDI (TR, buf[i], TR) 755 p.XORI (TR, buf[i], TR) 756 p.IQ (i, UR) 757 p.IP (v.Vt, ET) 758 p.BNE (TR, hir.Rz, LB_missing) 759 } 760 } 761 762 /* free the bitmap */ 763 p.SP (hir.Pn, EP, FmOffset) 764 p.GCALL (F_FieldBitmap_Free).A0(TP) 765 766 /* release the buffer */ 767 buf.Clear() 768 buf.Free() 769 } 770 771 func translate_OP_struct_is_stop(p *hir.Builder, v Instr) { 772 p.BEQ (TG, hir.Rz, p.At(v.To)) 773 } 774 775 func translate_OP_struct_mark_tag(p *hir.Builder, v Instr) { 776 p.ADDP (RS, ST, TP) 777 p.LP (TP, FmOffset, TP) 778 p.LQ (TP, v.Iv / 64 * 8, TR) 779 p.BSI (TR, v.Iv % 64, TR) 780 p.SQ (TR, TP, v.Iv / 64 * 8) 781 } 782 783 func translate_OP_struct_read_type(p *hir.Builder, _ Instr) { 784 p.ADDP (IP, IC, EP) 785 p.ADDI (IC, 1, IC) 786 p.LB (EP, 0, TG) 787 } 788 789 func translate_OP_struct_check_type(p *hir.Builder, v Instr) { 790 p.IB (int8(v.Tx), TR) 791 p.BNE (TG, TR, p.At(v.To)) 792 } 793 794 func translate_OP_make_state(p *hir.Builder, _ Instr) { 795 p.IQ (StateMax, TR) 796 p.BGEU (ST, TR, LB_overflow) 797 p.ADDP (RS, ST, TP) 798 p.SP (WP, TP, WpOffset) 799 p.ADDI (ST, StateSize, ST) 800 } 801 802 func translate_OP_drop_state(p *hir.Builder, _ Instr) { 803 p.SUBI (ST, StateSize, ST) 804 p.ADDP (RS, ST, TP) 805 p.LP (TP, WpOffset, WP) 806 p.SP (hir.Pn, TP, WpOffset) 807 } 808 809 func translate_OP_construct(p *hir.Builder, v Instr) { 810 p.IB (1, UR) 811 p.IP (v.Vt, TP) 812 p.IQ (int64(v.Vt.Size), TR) 813 p.GCALL (F_mallocgc). 814 A0 (TR). 815 A1 (TP). 816 A2 (UR). 817 R0 (WP) 818 } 819 820 func translate_OP_initialize(p *hir.Builder, v Instr) { 821 p.GCALL (addInitFn(v.Fn)). 822 A0 (WP) 823 } 824 825 func translate_OP_defer(p *hir.Builder, v Instr) { 826 p.IP (v.Vt, TP) 827 p.LDAQ (ARG_nb, TR) 828 p.GCALL (F_decode). 829 A0 (TP). 830 A1 (IP). 831 A2 (TR). 832 A3 (IC). 833 A4 (WP). 834 A5 (RS). 835 A6 (ST). 836 R0 (IC). 837 R1 (ET). 838 R2 (EP) 839 p.BNEP (ET, hir.Pn, LB_error) 840 } 841 842 func translate_OP_goto(p *hir.Builder, v Instr) { 843 p.JMP (p.At(v.To)) 844 } 845 846 func translate_OP_halt(p *hir.Builder, _ Instr) { 847 p.JMP (LB_halt) 848 }