github.com/cloudwego/iasm@v0.2.0/x86_64/encodings.go (about) 1 // 2 // Copyright 2024 CloudWeGo Authors 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 x86_64 18 19 import ( 20 `encoding/binary` 21 `math` 22 ) 23 24 /** Operand Encoding Helpers **/ 25 26 func imml(v interface{}) byte { 27 return byte(toImmAny(v) & 0x0f) 28 } 29 30 func relv(v interface{}) int64 { 31 switch r := v.(type) { 32 case *Label : return 0 33 case RelativeOffset : return int64(r) 34 default : panic("invalid relative offset") 35 } 36 } 37 38 func addr(v interface{}) interface{} { 39 switch a := v.(*MemoryOperand).Addr; a.Type { 40 case Memory : return a.Memory 41 case Offset : return a.Offset 42 case Reference : return a.Reference 43 default : panic("invalid memory operand type") 44 } 45 } 46 47 func bcode(v interface{}) byte { 48 if m, ok := v.(*MemoryOperand); !ok { 49 panic("v is not a memory operand") 50 } else if m.Broadcast == 0 { 51 return 0 52 } else { 53 return 1 54 } 55 } 56 57 func vcode(v interface{}) byte { 58 switch r := v.(type) { 59 case XMMRegister : return byte(r) 60 case YMMRegister : return byte(r) 61 case ZMMRegister : return byte(r) 62 case MaskedRegister : return vcode(r.Reg) 63 default : panic("v is not a vector register") 64 } 65 } 66 67 func kcode(v interface{}) byte { 68 switch r := v.(type) { 69 case KRegister : return byte(r) 70 case XMMRegister : return 0 71 case YMMRegister : return 0 72 case ZMMRegister : return 0 73 case RegisterMask : return byte(r.K) 74 case MaskedRegister : return byte(r.Mask.K) 75 case *MemoryOperand : return toKcodeMem(r) 76 default : panic("v is not a maskable operand") 77 } 78 } 79 80 func zcode(v interface{}) byte { 81 switch r := v.(type) { 82 case KRegister : return 0 83 case XMMRegister : return 0 84 case YMMRegister : return 0 85 case ZMMRegister : return 0 86 case RegisterMask : return toZcodeRegM(r) 87 case MaskedRegister : return toZcodeRegM(r.Mask) 88 case *MemoryOperand : return toZcodeMem(r) 89 default : panic("v is not a maskable operand") 90 } 91 } 92 93 func lcode(v interface{}) byte { 94 switch r := v.(type) { 95 case Register8 : return byte(r & 0x07) 96 case Register16 : return byte(r & 0x07) 97 case Register32 : return byte(r & 0x07) 98 case Register64 : return byte(r & 0x07) 99 case KRegister : return byte(r & 0x07) 100 case MMRegister : return byte(r & 0x07) 101 case XMMRegister : return byte(r & 0x07) 102 case YMMRegister : return byte(r & 0x07) 103 case ZMMRegister : return byte(r & 0x07) 104 case MaskedRegister : return lcode(r.Reg) 105 default : panic("v is not a register") 106 } 107 } 108 109 func hcode(v interface{}) byte { 110 switch r := v.(type) { 111 case Register8 : return byte(r >> 3) & 1 112 case Register16 : return byte(r >> 3) & 1 113 case Register32 : return byte(r >> 3) & 1 114 case Register64 : return byte(r >> 3) & 1 115 case KRegister : return byte(r >> 3) & 1 116 case MMRegister : return byte(r >> 3) & 1 117 case XMMRegister : return byte(r >> 3) & 1 118 case YMMRegister : return byte(r >> 3) & 1 119 case ZMMRegister : return byte(r >> 3) & 1 120 case MaskedRegister : return hcode(r.Reg) 121 default : panic("v is not a register") 122 } 123 } 124 125 func ecode(v interface{}) byte { 126 switch r := v.(type) { 127 case Register8 : return byte(r >> 4) & 1 128 case Register16 : return byte(r >> 4) & 1 129 case Register32 : return byte(r >> 4) & 1 130 case Register64 : return byte(r >> 4) & 1 131 case KRegister : return byte(r >> 4) & 1 132 case MMRegister : return byte(r >> 4) & 1 133 case XMMRegister : return byte(r >> 4) & 1 134 case YMMRegister : return byte(r >> 4) & 1 135 case ZMMRegister : return byte(r >> 4) & 1 136 case MaskedRegister : return ecode(r.Reg) 137 default : panic("v is not a register") 138 } 139 } 140 141 func hlcode(v interface{}) byte { 142 switch r := v.(type) { 143 case Register8 : return toHLcodeReg8(r) 144 case Register16 : return byte(r & 0x0f) 145 case Register32 : return byte(r & 0x0f) 146 case Register64 : return byte(r & 0x0f) 147 case KRegister : return byte(r & 0x0f) 148 case MMRegister : return byte(r & 0x0f) 149 case XMMRegister : return byte(r & 0x0f) 150 case YMMRegister : return byte(r & 0x0f) 151 case ZMMRegister : return byte(r & 0x0f) 152 case MaskedRegister : return hlcode(r.Reg) 153 default : panic("v is not a register") 154 } 155 } 156 157 func ehcode(v interface{}) byte { 158 switch r := v.(type) { 159 case Register8 : return byte(r >> 3) & 0x03 160 case Register16 : return byte(r >> 3) & 0x03 161 case Register32 : return byte(r >> 3) & 0x03 162 case Register64 : return byte(r >> 3) & 0x03 163 case KRegister : return byte(r >> 3) & 0x03 164 case MMRegister : return byte(r >> 3) & 0x03 165 case XMMRegister : return byte(r >> 3) & 0x03 166 case YMMRegister : return byte(r >> 3) & 0x03 167 case ZMMRegister : return byte(r >> 3) & 0x03 168 case MaskedRegister : return ehcode(r.Reg) 169 default : panic("v is not a register") 170 } 171 } 172 173 func toImmAny(v interface{}) int64 { 174 if x, ok := asInt64(v); ok { 175 return x 176 } else { 177 panic("value is not an integer") 178 } 179 } 180 181 func toHcodeOpt(v interface{}) byte { 182 if v == nil { 183 return 0 184 } else { 185 return hcode(v) 186 } 187 } 188 189 func toEcodeVMM(v interface{}, x byte) byte { 190 switch r := v.(type) { 191 case XMMRegister : return ecode(r) 192 case YMMRegister : return ecode(r) 193 case ZMMRegister : return ecode(r) 194 default : return x 195 } 196 } 197 198 func toKcodeMem(v *MemoryOperand) byte { 199 if !v.Masked { 200 return 0 201 } else { 202 return byte(v.Mask.K) 203 } 204 } 205 206 func toZcodeMem(v *MemoryOperand) byte { 207 if !v.Masked || v.Mask.Z { 208 return 0 209 } else { 210 return 1 211 } 212 } 213 214 func toZcodeRegM(v RegisterMask) byte { 215 if v.Z { 216 return 1 217 } else { 218 return 0 219 } 220 } 221 222 func toHLcodeReg8(v Register8) byte { 223 switch v { 224 case AH: fallthrough 225 case BH: fallthrough 226 case CH: fallthrough 227 case DH: panic("ah/bh/ch/dh registers never use 4-bit encoding") 228 default: return byte(v & 0x0f) 229 } 230 } 231 232 /** Instruction Encoding Helpers **/ 233 234 const ( 235 _N_inst = 16 236 ) 237 238 const ( 239 _F_rel1 = 1 << iota 240 _F_rel4 241 ) 242 243 type _Encoding struct { 244 len int 245 flags int 246 bytes [_N_inst]byte 247 encoder func(m *_Encoding, v []interface{}) 248 } 249 250 // buf ensures len + n <= len(bytes). 251 func (self *_Encoding) buf(n int) []byte { 252 if i := self.len; i + n > _N_inst { 253 panic("instruction too long") 254 } else { 255 return self.bytes[i:] 256 } 257 } 258 259 // emit encodes a single byte. 260 func (self *_Encoding) emit(v byte) { 261 self.buf(1)[0] = v 262 self.len++ 263 } 264 265 // imm1 encodes a single byte immediate value. 266 func (self *_Encoding) imm1(v int64) { 267 self.emit(byte(v)) 268 } 269 270 // imm2 encodes a two-byte immediate value in little-endian. 271 func (self *_Encoding) imm2(v int64) { 272 binary.LittleEndian.PutUint16(self.buf(2), uint16(v)) 273 self.len += 2 274 } 275 276 // imm4 encodes a 4-byte immediate value in little-endian. 277 func (self *_Encoding) imm4(v int64) { 278 binary.LittleEndian.PutUint32(self.buf(4), uint32(v)) 279 self.len += 4 280 } 281 282 // imm8 encodes an 8-byte immediate value in little-endian. 283 func (self *_Encoding) imm8(v int64) { 284 binary.LittleEndian.PutUint64(self.buf(8), uint64(v)) 285 self.len += 8 286 } 287 288 // vex2 encodes a 2-byte or 3-byte VEX prefix. 289 // 290 // 2-byte VEX prefix: 291 // Requires: VEX.W = 0, VEX.mmmmm = 0b00001 and VEX.B = VEX.X = 0 292 // +----------------+ 293 // Byte 0: | Bits 0-7: 0xc5 | 294 // +----------------+ 295 // 296 // +-----------+----------------+----------+--------------+ 297 // Byte 1: | Bit 7: ~R | Bits 3-6 ~vvvv | Bit 2: L | Bits 0-1: pp | 298 // +-----------+----------------+----------+--------------+ 299 // 300 // 3-byte VEX prefix: 301 // +----------------+ 302 // Byte 0: | Bits 0-7: 0xc4 | 303 // +----------------+ 304 // 305 // +-----------+-----------+-----------+-------------------+ 306 // Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: 0b00001 | 307 // +-----------+-----------+-----------+-------------------+ 308 // 309 // +----------+-----------------+----------+--------------+ 310 // Byte 2: | Bit 7: 0 | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp | 311 // +----------+-----------------+----------+--------------+ 312 // 313 func (self *_Encoding) vex2(lpp byte, r byte, rm interface{}, vvvv byte) { 314 var b byte 315 var x byte 316 317 /* VEX.R must be a single-bit mask */ 318 if r > 1 { 319 panic("VEX.R must be a 1-bit mask") 320 } 321 322 /* VEX.Lpp must be a 3-bit mask */ 323 if lpp &^ 0b111 != 0 { 324 panic("VEX.Lpp must be a 3-bit mask") 325 } 326 327 /* VEX.vvvv must be a 4-bit mask */ 328 if vvvv &^ 0b1111 != 0 { 329 panic("VEX.vvvv must be a 4-bit mask") 330 } 331 332 /* encode the RM bits if any */ 333 if rm != nil { 334 switch v := rm.(type) { 335 case *Label : break 336 case Register : b = hcode(v) 337 case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index) 338 case RelativeOffset : break 339 default : panic("rm is expected to be a register or a memory address") 340 } 341 } 342 343 /* if VEX.B and VEX.X are zeroes, 2-byte VEX prefix can be used */ 344 if x == 0 && b == 0 { 345 self.emit(0xc5) 346 self.emit(0xf8 ^ (r << 7) ^ (vvvv << 3) ^ lpp) 347 } else { 348 self.emit(0xc4) 349 self.emit(0xe1 ^ (r << 7) ^ (x << 6) ^ (b << 5)) 350 self.emit(0x78 ^ (vvvv << 3) ^ lpp) 351 } 352 } 353 354 // vex3 encodes a 3-byte VEX or XOP prefix. 355 // 356 // 3-byte VEX/XOP prefix 357 // +-----------------------------------+ 358 // Byte 0: | Bits 0-7: 0xc4 (VEX) / 0x8f (XOP) | 359 // +-----------------------------------+ 360 // 361 // +-----------+-----------+-----------+-----------------+ 362 // Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: mmmmm | 363 // +-----------+-----------+-----------+-----------------+ 364 // 365 // +----------+-----------------+----------+--------------+ 366 // Byte 2: | Bit 7: W | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp | 367 // +----------+-----------------+----------+--------------+ 368 // 369 func (self *_Encoding) vex3(esc byte, mmmmm byte, wlpp byte, r byte, rm interface{}, vvvv byte) { 370 var b byte 371 var x byte 372 373 /* VEX.R must be a single-bit mask */ 374 if r > 1 { 375 panic("VEX.R must be a 1-bit mask") 376 } 377 378 /* VEX.vvvv must be a 4-bit mask */ 379 if vvvv &^ 0b1111 != 0 { 380 panic("VEX.vvvv must be a 4-bit mask") 381 } 382 383 /* escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix */ 384 if esc != 0xc4 && esc != 0x8f { 385 panic("escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix") 386 } 387 388 /* VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7 */ 389 if wlpp &^ 0b10000111 != 0 { 390 panic("VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7") 391 } 392 393 /* VEX.m-mmmm is expected to be a 5-bit mask */ 394 if mmmmm &^ 0b11111 != 0 { 395 panic("VEX.m-mmmm is expected to be a 5-bit mask") 396 } 397 398 /* encode the RM bits */ 399 switch v := rm.(type) { 400 case *Label : break 401 case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index) 402 case RelativeOffset : break 403 default : panic("rm is expected to be a register or a memory address") 404 } 405 406 /* encode the 3-byte VEX or XOP prefix */ 407 self.emit(esc) 408 self.emit(0xe0 ^ (r << 7) ^ (x << 6) ^ (b << 5) ^ mmmmm) 409 self.emit(0x78 ^ (vvvv << 3) ^ wlpp) 410 } 411 412 // evex encodes a 4-byte EVEX prefix. 413 func (self *_Encoding) evex(mm byte, w1pp byte, ll byte, rr byte, rm interface{}, vvvvv byte, aaa byte, zz byte, bb byte) { 414 var b byte 415 var x byte 416 417 /* EVEX.b must be a single-bit mask */ 418 if bb > 1 { 419 panic("EVEX.b must be a 1-bit mask") 420 } 421 422 /* EVEX.z must be a single-bit mask */ 423 if zz > 1 { 424 panic("EVEX.z must be a 1-bit mask") 425 } 426 427 /* EVEX.mm must be a 2-bit mask */ 428 if mm &^ 0b11 != 0 { 429 panic("EVEX.mm must be a 2-bit mask") 430 } 431 432 /* EVEX.L'L must be a 2-bit mask */ 433 if ll &^ 0b11 != 0 { 434 panic("EVEX.L'L must be a 2-bit mask") 435 } 436 437 /* EVEX.R'R must be a 2-bit mask */ 438 if rr &^ 0b11 != 0 { 439 panic("EVEX.R'R must be a 2-bit mask") 440 } 441 442 /* EVEX.aaa must be a 3-bit mask */ 443 if aaa &^ 0b111 != 0 { 444 panic("EVEX.aaa must be a 3-bit mask") 445 } 446 447 /* EVEX.v'vvvv must be a 5-bit mask */ 448 if vvvvv &^ 0b11111 != 0 { 449 panic("EVEX.v'vvvv must be a 5-bit mask") 450 } 451 452 /* EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7 */ 453 if w1pp &^ 0b10000011 != 0b100 { 454 panic("EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7") 455 } 456 457 /* extract bits from EVEX.R'R and EVEX.v'vvvv */ 458 r1, r0 := rr >> 1, rr & 1 459 v1, v0 := vvvvv >> 4, vvvvv & 0b1111 460 461 /* encode the RM bits if any */ 462 if rm != nil { 463 switch m := rm.(type) { 464 case *Label : break 465 case Register : b, x = hcode(m), ecode(m) 466 case MemoryAddress : b, x, v1 = toHcodeOpt(m.Base), toHcodeOpt(m.Index), toEcodeVMM(m.Index, v1) 467 case RelativeOffset : break 468 default : panic("rm is expected to be a register or a memory address") 469 } 470 } 471 472 /* EVEX prefix bytes */ 473 p0 := (r0 << 7) | (x << 6) | (b << 5) | (r1 << 4) | mm 474 p1 := (v0 << 3) | w1pp 475 p2 := (zz << 7) | (ll << 5) | (b << 4) | (v1 << 3) | aaa 476 477 /* p0: invert RXBR' (bits 4-7) 478 * p1: invert vvvv (bits 3-6) 479 * p2: invert V' (bit 3) */ 480 self.emit(0x62) 481 self.emit(p0 ^ 0xf0) 482 self.emit(p1 ^ 0x78) 483 self.emit(p2 ^ 0x08) 484 } 485 486 // rexm encodes a mandatory REX prefix. 487 func (self *_Encoding) rexm(w byte, r byte, rm interface{}) { 488 var b byte 489 var x byte 490 491 /* REX.R must be 0 or 1 */ 492 if r != 0 && r != 1 { 493 panic("REX.R must be 0 or 1") 494 } 495 496 /* REX.W must be 0 or 1 */ 497 if w != 0 && w != 1 { 498 panic("REX.W must be 0 or 1") 499 } 500 501 /* encode the RM bits */ 502 switch v := rm.(type) { 503 case *Label : break 504 case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index) 505 case RelativeOffset : break 506 default : panic("rm is expected to be a register or a memory address") 507 } 508 509 /* encode the REX prefix */ 510 self.emit(0x40 | (w << 3) | (r << 2) | (x << 1) | b) 511 } 512 513 // rexo encodes an optional REX prefix. 514 func (self *_Encoding) rexo(r byte, rm interface{}, force bool) { 515 var b byte 516 var x byte 517 518 /* REX.R must be 0 or 1 */ 519 if r != 0 && r != 1 { 520 panic("REX.R must be 0 or 1") 521 } 522 523 /* encode the RM bits */ 524 switch v := rm.(type) { 525 case *Label : break 526 case Register : b = hcode(v) 527 case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index) 528 case RelativeOffset : break 529 default : panic("rm is expected to be a register or a memory address") 530 } 531 532 /* if REX.R, REX.X, and REX.B are all zeroes, REX prefix can be omitted */ 533 if force || r != 0 || x != 0 || b != 0 { 534 self.emit(0x40 | (r << 2) | (x << 1) | b) 535 } 536 } 537 538 // mrsd encodes ModR/M, SIB and Displacement. 539 // 540 // ModR/M byte 541 // +----------------+---------------+---------------+ 542 // | Bits 6-7: Mode | Bits 3-5: Reg | Bits 0-2: R/M | 543 // +----------------+---------------+---------------+ 544 // 545 // SIB byte 546 // +-----------------+-----------------+----------------+ 547 // | Bits 6-7: Scale | Bits 3-5: Index | Bits 0-2: Base | 548 // +-----------------+-----------------+----------------+ 549 // 550 func (self *_Encoding) mrsd(reg byte, rm interface{}, disp8v int32) { 551 var ok bool 552 var mm MemoryAddress 553 var ro RelativeOffset 554 555 /* ModRM encodes the lower 3-bit of the register */ 556 if reg > 7 { 557 panic("invalid register bits") 558 } 559 560 /* check the displacement scale */ 561 switch disp8v { 562 case 1: break 563 case 2: break 564 case 4: break 565 case 8: break 566 case 16: break 567 case 32: break 568 case 64: break 569 default: panic("invalid displacement size") 570 } 571 572 /* special case: unresolved labels, assuming a zero offset */ 573 if _, ok = rm.(*Label); ok { 574 self.emit(0x05 | (reg << 3)) 575 self.imm4(0) 576 return 577 } 578 579 /* special case: RIP-relative offset 580 * ModRM.Mode == 0 and ModeRM.R/M == 5 indicates (rip + disp32) addressing */ 581 if ro, ok = rm.(RelativeOffset); ok { 582 self.emit(0x05 | (reg << 3)) 583 self.imm4(int64(ro)) 584 return 585 } 586 587 /* must be a generic memory address */ 588 if mm, ok = rm.(MemoryAddress); !ok { 589 panic("rm must be a memory address") 590 } 591 592 /* absolute addressing, encoded as disp(%rbp,%rsp,1) */ 593 if mm.Base == nil && mm.Index == nil { 594 self.emit(0x04 | (reg << 3)) 595 self.emit(0x25) 596 self.imm4(int64(mm.Displacement)) 597 return 598 } 599 600 /* no SIB byte */ 601 if mm.Index == nil && lcode(mm.Base) != 0b100 { 602 cc := lcode(mm.Base) 603 dv := mm.Displacement 604 605 /* ModRM.Mode == 0 (no displacement) */ 606 if dv == 0 && mm.Base != RBP && mm.Base != R13 { 607 if cc == 0b101 { 608 panic("rbp/r13 is not encodable as a base register (interpreted as disp32 address)") 609 } else { 610 self.emit((reg << 3) | cc) 611 return 612 } 613 } 614 615 /* ModRM.Mode == 1 (8-bit displacement) */ 616 if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv % disp8v == 0 { 617 self.emit(0x40 | (reg << 3) | cc) 618 self.imm1(int64(dq)) 619 return 620 } 621 622 /* ModRM.Mode == 2 (32-bit displacement) */ 623 self.emit(0x80 | (reg << 3) | cc) 624 self.imm4(int64(mm.Displacement)) 625 return 626 } 627 628 /* all encodings below use ModRM.R/M = 4 (0b100) to indicate the presence of SIB */ 629 if mm.Index == RSP { 630 panic("rsp is not encodable as an index register (interpreted as no index)") 631 } 632 633 /* index = 4 (0b100) denotes no-index encoding */ 634 var scale byte 635 var index byte = 0x04 636 637 /* encode the scale byte */ 638 if mm.Scale != 0 { 639 switch mm.Scale { 640 case 1 : scale = 0 641 case 2 : scale = 1 642 case 4 : scale = 2 643 case 8 : scale = 3 644 default : panic("invalid scale value") 645 } 646 } 647 648 /* encode the index byte */ 649 if mm.Index != nil { 650 index = lcode(mm.Index) 651 } 652 653 /* SIB.Base = 5 (0b101) and ModRM.Mode = 0 indicates no-base encoding with disp32 */ 654 if mm.Base == nil { 655 self.emit((reg << 3) | 0b100) 656 self.emit((scale << 6) | (index << 3) | 0b101) 657 self.imm4(int64(mm.Displacement)) 658 return 659 } 660 661 /* base L-code & displacement value */ 662 cc := lcode(mm.Base) 663 dv := mm.Displacement 664 665 /* ModRM.Mode == 0 (no displacement) */ 666 if dv == 0 && cc != 0b101 { 667 self.emit((reg << 3) | 0b100) 668 self.emit((scale << 6) | (index << 3) | cc) 669 return 670 } 671 672 /* ModRM.Mode == 1 (8-bit displacement) */ 673 if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv % disp8v == 0 { 674 self.emit(0x44 | (reg << 3)) 675 self.emit((scale << 6) | (index << 3) | cc) 676 self.imm1(int64(dq)) 677 return 678 } 679 680 /* ModRM.Mode == 2 (32-bit displacement) */ 681 self.emit(0x84 | (reg << 3)) 682 self.emit((scale << 6) | (index << 3) | cc) 683 self.imm4(int64(mm.Displacement)) 684 } 685 686 // encode invokes the encoder to encode this instruction. 687 func (self *_Encoding) encode(v []interface{}) int { 688 self.len = 0 689 self.encoder(self, v) 690 return self.len 691 }