src/host/buildvm_arch.h - luajit-2.0-src

Global variables defined

Functions defined

Macros defined

Source code

  1. /*
  2. ** This file has been pre-processed with DynASM.
  3. ** http://luajit.org/dynasm.html
  4. ** DynASM version 1.3.0, DynASM x64 version 1.3.0
  5. ** DO NOT EDIT! The original file is in "vm_x86.dasc".
  6. */

  7. #line 1 "vm_x86.dasc"
  8. //|// Low-level VM code for x86 CPUs.
  9. //|// Bytecode interpreter, fast functions and helper functions.
  10. //|// Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
  11. //|
  12. //|.if P64
  13. //|.arch x64
  14. #if DASM_VERSION != 10300
  15. #error "Version mismatch between DynASM and included encoding engine"
  16. #endif
  17. #line 7 "vm_x86.dasc"
  18. //|.else
  19. //|.arch x86
  20. //|.endif
  21. //|.section code_op, code_sub
  22. #define DASM_SECTION_CODE_OP        0
  23. #define DASM_SECTION_CODE_SUB        1
  24. #define DASM_MAXSECTION                2
  25. #line 11 "vm_x86.dasc"
  26. //|
  27. //|.actionlist build_actionlist
  28. static const unsigned char build_actionlist[14864] = {
  29.   254,1,248,10,252,247,195,237,15,132,244,11,131,227,252,248,41,218,72,141,
  30.   76,25,252,248,139,90,252,252,199,68,10,4,237,248,12,131,192,1,15,132,244,
  31.   13,137,68,36,4,252,247,195,237,15,132,244,14,248,15,129,252,243,239,252,247,
  32.   195,237,15,133,244,10,65,199,134,233,237,131,227,252,248,41,211,252,247,219,
  33.   131,232,1,15,132,244,248,248,1,255,72,139,44,10,72,137,106,252,248,131,194,
  34.   8,131,232,1,15,133,244,1,248,2,139,108,36,24,137,157,233,248,3,139,68,36,
  35.   4,139,76,36,16,248,4,57,193,15,133,244,252,248,5,131,252,234,8,137,149,233,
  36.   248,16,72,139,76,36,32,72,137,141,233,49,192,248,17,72,131,196,40,65,94,65,
  37.   95,91,93,195,248,6,15,130,244,253,59,149,233,15,135,244,254,199,66,252,252,
  38.   237,255,131,194,8,131,192,1,252,233,244,4,248,7,133,201,15,132,244,5,41,193,
  39.   141,20,202,252,233,244,5,248,8,137,149,233,137,68,36,4,137,206,137,252,239,
  40.   232,251,1,0,139,149,233,252,233,244,3,248,13,176,235,252,233,244,18,248,19,
  41.   137,252,240,72,137,252,252,248,18,139,108,36,24,139,173,233,199,133,233,237,
  42.   255,252,233,244,17,248,20,139,124,36,24,137,198,72,131,196,40,65,94,65,95,
  43.   91,93,252,233,251,1,1,248,21,72,129,231,239,72,137,252,252,248,22,139,108,
  44.   36,24,72,199,193,252,248,252,255,252,255,252,255,184,237,139,149,233,68,139,
  45.   181,233,65,129,198,239,139,90,252,252,199,66,252,252,237,65,199,134,233,237,
  46.   252,233,244,12,248,23,190,237,252,233,244,248,248,24,255,131,232,8,252,233,
  47.   244,247,248,25,141,68,194,252,248,248,1,15,182,139,233,131,195,4,137,149,
  48.   233,137,133,233,137,92,36,28,137,206,248,2,137,252,239,232,251,1,0,139,149,
  49.   233,139,133,233,139,106,252,248,41,208,193,232,3,131,192,1,139,157,233,139,
  50.   11,15,182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,248,26,85,83,
  51.   65,87,65,86,72,131,252,236,40,137,252,253,137,124,36,24,137,252,241,187,237,
  52.   49,192,76,141,188,253,36,233,68,139,181,233,65,129,198,239,137,68,36,28,72,
  53.   137,68,36,32,137,68,36,16,137,68,36,20,76,137,189,233,56,133,233,15,132,244,
  54.   248,255,65,137,174,233,65,199,134,233,237,136,133,233,139,149,233,139,133,
  55.   233,41,200,193,232,3,131,192,1,41,209,139,90,252,252,137,68,36,4,252,247,
  56.   195,237,15,132,244,14,252,233,244,15,248,27,85,83,65,87,65,86,72,131,252,
  57.   236,40,187,237,137,76,36,20,252,233,244,247,248,28,85,83,65,87,65,86,72,131,
  58.   252,236,40,187,237,248,1,137,84,36,16,137,252,253,137,124,36,24,137,252,241,
  59.   68,139,181,233,76,139,189,233,255,76,137,124,36,32,137,108,36,28,65,129,198,
  60.   239,72,137,165,233,248,2,65,137,174,233,65,199,134,233,237,139,149,233,1,
  61.   203,41,211,139,133,233,41,200,193,232,3,131,192,1,248,29,139,105,252,248,
  62.   129,121,253,252,252,239,15,133,244,30,248,31,137,202,137,90,252,252,139,157,
  63.   233,139,11,15,182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,248,
  64.   32,85,83,65,87,65,86,72,131,252,236,40,137,252,253,137,124,36,24,137,108,
  65.   36,28,68,139,189,233,68,43,189,233,68,139,181,233,199,68,36,20,0,0,0,0,68,
  66.   137,124,36,16,65,129,198,239,76,139,189,233,255,76,137,124,36,32,72,137,165,
  67.   233,65,137,174,233,252,255,209,133,192,15,132,244,16,137,193,187,237,252,
  68.   233,244,2,248,11,1,209,131,227,252,248,137,213,41,218,199,68,193,252,252,
  69.   237,137,200,139,93,252,244,72,99,77,252,240,131,252,249,1,15,134,244,247,
  70.   76,141,61,245,76,1,252,249,68,139,122,252,248,69,139,191,233,69,139,191,233,
  71.   252,255,225,248,1,15,132,244,33,41,213,193,252,237,3,141,69,252,255,252,233,
  72.   244,34,248,35,255,15,182,75,252,255,131,252,237,16,141,12,202,41,252,233,
  73.   15,132,244,36,252,247,217,193,252,233,3,139,124,36,24,137,151,233,137,202,
  74.   72,139,8,72,137,77,0,137,252,238,252,233,244,37,248,38,137,4,36,199,68,36,
  75.   4,237,72,141,4,36,128,123,252,252,235,15,133,244,247,65,141,142,233,137,41,
  76.   199,65,4,237,137,205,252,233,244,248,248,39,15,182,67,252,254,199,68,36,4,
  77.   237,137,4,36,72,141,4,36,252,233,244,247,248,40,15,182,67,252,254,141,4,194,
  78.   248,1,255,15,182,107,252,255,141,44,252,234,248,2,139,124,36,24,137,151,233,
  79.   137,252,238,72,137,194,137,252,253,137,92,36,28,232,251,1,2,139,149,233,133,
  80.   192,15,132,244,249,248,36,15,182,75,252,253,72,139,40,72,137,44,202,139,3,
  81.   15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,3,139,
  82.   141,233,137,89,252,244,141,153,233,41,211,139,105,252,248,184,237,252,233,
  83.   244,31,248,41,137,252,239,137,213,137,198,232,251,1,3,15,182,75,252,253,137,
  84.   252,234,133,192,15,133,244,42,199,68,202,4,237,252,233,244,43,248,44,137,
  85.   4,36,199,68,36,4,237,255,72,141,4,36,128,123,252,252,235,15,133,244,247,65,
  86.   141,142,233,137,41,199,65,4,237,137,205,252,233,244,248,248,45,15,182,67,
  87.   252,254,199,68,36,4,237,137,4,36,72,141,4,36,252,233,244,247,248,46,15,182,
  88.   67,252,254,141,4,194,248,1,15,182,107,252,255,141,44,252,234,248,2,139,124,
  89.   36,24,137,151,233,137,252,238,72,137,194,137,252,253,137,92,36,28,232,251,
  90.   1,4,139,149,233,133,192,15,132,244,249,15,182,75,252,253,72,139,44,202,72,
  91.   137,40,248,47,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,
  92.   36,252,238,248,3,255,139,141,233,137,89,252,244,15,182,67,252,253,72,139,
  93.   44,194,72,137,105,16,141,153,233,41,211,139,105,252,248,184,237,252,233,244,
  94.   31,248,48,139,124,36,24,137,252,238,137,151,233,137,213,137,194,137,92,36,
  95.   28,232,251,1,5,15,182,75,252,253,137,252,234,252,233,244,49,248,50,139,108,
  96.   36,24,137,149,233,141,52,202,141,20,194,137,252,239,15,182,75,252,252,137,
  97.   92,36,28,232,251,1,6,248,3,139,149,233,131,252,248,1,15,135,244,51,248,4,
  98.   141,91,4,15,130,244,252,248,5,15,183,67,252,254,141,156,253,131,233,248,6,
  99.   255,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,
  100.   248,52,131,195,4,129,120,253,4,239,15,130,244,5,252,233,244,6,248,53,129,
  101.   120,253,4,239,252,233,244,4,248,54,131,252,235,4,137,206,137,252,233,139,
  102.   108,36,24,137,149,233,137,194,137,252,239,137,92,36,28,232,251,1,7,252,233,
  103.   244,3,248,55,131,252,235,4,139,108,36,24,137,149,233,137,252,239,139,115,
  104.   252,252,137,92,36,28,232,251,1,8,252,233,244,3,248,56,139,108,36,24,137,149,
  105.   233,255,137,206,15,183,83,252,254,137,252,239,137,92,36,28,232,251,1,9,139,
  106.   149,233,252,233,244,6,248,57,15,182,107,252,255,248,58,65,141,4,199,252,233,
  107.   244,247,248,59,15,182,67,252,254,248,60,65,141,4,199,141,44,252,234,149,252,
  108.   233,244,248,248,61,141,4,194,137,197,252,233,244,248,248,62,15,182,107,252,
  109.   255,248,63,141,4,194,248,1,141,44,252,234,248,2,141,12,202,68,15,182,67,252,
  110.   252,137,206,137,193,139,124,36,24,137,151,233,137,252,234,137,252,253,137,
  111.   92,36,28,232,251,1,10,139,149,233,255,133,192,15,132,244,47,248,51,137,193,
  112.   41,208,137,89,252,244,141,152,233,184,237,252,233,244,29,248,64,139,108,36,
  113.   24,137,149,233,141,52,194,137,252,239,137,92,36,28,232,251,1,11,139,149,233,
  114.   255,133,192,15,133,244,51,15,183,67,252,254,139,60,194,252,233,244,65,255,
  115.   252,233,244,51,255,248,66,141,76,202,8,248,30,137,76,36,4,137,4,36,131,252,
  116.   233,8,139,108,36,24,137,149,233,137,206,141,20,193,137,252,239,137,92,36,
  117.   28,232,251,1,12,139,149,233,139,76,36,4,139,4,36,139,105,252,248,131,192,
  118.   1,65,57,215,15,132,244,67,137,202,137,90,252,252,139,157,233,139,11,15,182,
  119.   252,233,15,182,205,131,195,4,65,252,255,36,252,238,248,68,139,108,36,24,137,
  120.   149,233,137,206,137,252,239,137,92,36,28,232,251,1,13,139,149,233,139,67,
  121.   252,252,15,182,204,15,182,232,193,232,16,65,252,255,164,253,252,238,233,248,
  122.   69,129,252,248,239,15,130,244,70,139,106,4,129,252,253,239,15,131,244,70,
  123.   139,90,252,252,137,68,36,4,137,106,252,252,139,42,137,106,252,248,131,232,
  124.   2,15,132,244,248,255,137,209,248,1,131,193,8,72,139,41,72,137,105,252,248,
  125.   131,232,1,15,133,244,1,248,2,139,68,36,4,252,233,244,71,248,72,129,252,248,
  126.   239,15,130,244,70,139,106,4,137,252,233,193,252,249,15,131,252,249,252,254,
  127.   15,132,244,249,184,237,252,247,213,57,232,15,71,197,248,2,139,106,252,248,
  128.   139,132,253,197,233,139,90,252,252,199,66,252,252,237,137,66,252,248,252,
  129.   233,244,73,248,3,184,237,255,252,233,244,2,248,74,129,252,248,239,15,130,
  130.   244,70,139,106,4,139,90,252,252,129,252,253,239,15,133,244,252,248,1,139,
  131.   42,139,173,233,248,2,133,252,237,199,66,252,252,237,15,132,244,73,65,139,
  132.   134,233,199,66,252,252,237,137,106,252,248,139,141,233,35,136,233,105,201,
  133.   239,255,3,141,233,248,3,129,185,233,239,15,133,244,250,57,129,233,15,132,
  134.   244,251,248,4,139,137,233,133,201,15,133,244,3,252,233,244,73,248,5,139,105,
  135.   4,129,252,253,239,15,132,244,73,139,1,137,106,252,252,137,66,252,248,252,
  136.   233,244,73,248,6,255,129,252,253,239,15,132,244,1,129,252,253,239,15,135,
  137.   244,254,129,252,253,239,15,134,244,253,189,237,252,233,244,254,248,7,189,
  138.   237,248,8,252,247,213,65,139,172,253,174,233,252,233,244,2,248,75,129,252,
  139.   248,239,255,15,130,244,70,129,122,253,4,239,15,133,244,70,139,42,131,189,
  140.   233,0,15,133,244,70,129,122,253,12,239,15,133,244,70,139,66,8,137,133,233,
  141.   139,90,252,252,199,66,252,252,237,137,106,252,248,252,246,133,233,235,15,
  142.   132,244,247,128,165,233,235,65,139,134,233,255,65,137,174,233,137,133,233,
  143.   248,1,252,233,244,73,248,76,129,252,248,239,15,130,244,70,129,122,253,4,239,
  144.   15,133,244,70,137,213,139,50,141,82,8,139,124,36,24,232,251,1,14,137,252,
  145.   234,72,139,40,139,90,252,252,72,137,106,252,248,252,233,244,73,248,77,129,
  146.   252,248,239,15,133,244,70,129,122,253,4,239,15,133,244,247,255,139,42,252,
  147.   233,244,78,248,1,15,135,244,70,252,242,15,16,2,252,233,244,79,248,80,129,
  148.   252,248,239,15,130,244,70,139,90,252,252,129,122,253,4,239,15,133,244,249,
  149.   139,2,248,2,199,66,252,252,237,137,66,252,248,252,233,244,73,248,3,129,122,
  150.   253,4,239,255,15,135,244,70,65,131,190,233,0,15,133,244,70,65,139,174,233,
  151.   65,59,174,233,15,130,244,247,232,244,81,248,1,139,108,36,24,137,149,233,137,
  152.   92,36,28,137,214,137,252,239,232,251,1,15,139,149,233,252,233,244,2,248,82,
  153.   129,252,248,239,15,130,244,70,255,15,132,244,248,248,1,129,122,253,4,239,
  154.   15,133,244,70,139,108,36,24,137,149,233,137,149,233,139,90,252,252,139,50,
  155.   141,82,8,137,252,239,137,92,36,28,232,251,1,16,139,149,233,133,192,15,132,
  156.   244,249,72,139,106,8,72,139,66,16,72,137,106,252,248,72,137,2,248,83,184,
  157.   237,252,233,244,84,248,2,199,66,12,237,252,233,244,1,248,3,255,199,66,252,
  158.   252,237,252,233,244,73,248,85,129,252,248,239,15,130,244,70,139,42,129,122,
  159.   253,4,239,15,133,244,70,255,131,189,233,0,15,133,244,70,255,139,106,252,248,
  160.   139,133,233,139,90,252,252,199,66,252,252,237,137,66,252,248,199,66,12,237,
  161.   184,237,252,233,244,84,248,86,129,252,248,239,15,130,244,70,129,122,253,4,
  162.   239,15,133,244,70,129,122,253,12,239,15,133,244,70,139,90,252,252,139,66,
  163.   8,131,192,1,199,66,252,252,237,137,66,252,248,139,42,59,133,233,15,131,244,
  164.   248,255,193,224,3,3,133,233,248,1,129,120,253,4,239,15,132,244,87,72,139,
  165.   40,72,137,42,252,233,244,83,248,2,131,189,233,0,15,132,244,87,137,252,239,
  166.   137,213,137,198,232,251,1,3,137,252,234,133,192,15,133,244,1,248,87,184,237,
  167.   252,233,244,84,248,88,129,252,248,239,15,130,244,70,255,139,106,252,248,139,
  168.   133,233,139,90,252,252,199,66,252,252,237,137,66,252,248,199,66,12,237,199,
  169.   66,8,0,0,0,0,184,237,252,233,244,84,248,89,129,252,248,239,15,130,244,70,
  170.   141,74,8,131,232,1,187,237,248,1,65,15,182,174,233,193,252,237,235,131,229,
  171.   1,1,252,235,252,233,244,29,248,90,129,252,248,239,15,130,244,70,255,129,122,
  172.   253,12,239,15,133,244,70,139,106,4,137,106,12,199,66,4,237,139,42,139,90,
  173.   8,137,106,8,137,26,141,74,16,131,232,2,187,237,252,233,244,1,248,91,129,252,
  174.   248,239,15,130,244,70,139,42,139,90,252,252,137,92,36,28,137,44,36,129,122,
  175.   253,4,239,15,133,244,70,72,131,189,233,0,15,133,244,70,128,189,233,235,15,
  176.   135,244,70,255,139,141,233,15,132,244,247,59,141,233,15,132,244,70,248,1,
  177.   141,92,193,252,240,59,157,233,15,135,244,70,137,157,233,139,108,36,24,137,
  178.   149,233,131,194,8,137,149,233,141,108,194,232,72,41,221,57,203,15,132,244,
  179.   249,248,2,72,139,4,43,72,137,67,252,248,131,252,235,8,57,203,15,133,244,2,
  180.   248,3,137,206,139,60,36,232,244,26,255,139,108,36,24,139,28,36,139,149,233,
  181.   65,137,174,233,65,199,134,233,237,129,252,248,239,15,135,244,254,248,4,139,
  182.   139,233,68,139,187,233,137,139,233,68,137,252,251,41,203,15,132,244,252,141,
  183.   4,26,193,252,235,3,59,133,233,15,135,244,255,137,213,72,41,205,248,5,72,139,
  184.   1,72,137,4,41,131,193,8,68,57,252,249,15,133,244,5,248,6,255,141,67,2,199,
  185.   66,252,252,237,248,7,139,92,36,28,137,68,36,4,72,199,193,252,248,252,255,
  186.   252,255,252,255,252,247,195,237,15,132,244,14,252,233,244,15,248,8,199,66,
  187.   252,252,237,139,139,233,131,252,233,8,137,139,233,72,139,1,72,137,2,184,237,
  188.   252,233,244,7,248,9,139,12,36,68,137,185,233,137,222,137,252,239,232,251,
  189.   1,0,139,28,36,139,149,233,252,233,244,4,248,92,255,139,106,252,248,139,173,
  190.   233,139,90,252,252,137,92,36,28,137,44,36,72,131,189,233,0,15,133,244,70,
  191.   128,189,233,235,15,135,244,70,139,141,233,15,132,244,247,59,141,233,15,132,
  192.   244,70,248,1,141,92,193,252,248,59,157,233,15,135,244,70,137,157,233,139,
  193.   108,36,24,137,149,233,255,137,149,233,141,108,194,252,240,72,41,221,57,203,
  194.   15,132,244,249,248,2,72,139,4,43,72,137,67,252,248,131,252,235,8,57,203,15,
  195.   133,244,2,248,3,137,206,139,60,36,232,244,26,139,108,36,24,139,28,36,139,
  196.   149,233,65,137,174,233,65,199,134,233,237,129,252,248,239,15,135,244,254,
  197.   248,4,139,139,233,68,139,187,233,137,139,233,255,68,137,252,251,41,203,15,
  198.   132,244,252,141,4,26,193,252,235,3,59,133,233,15,135,244,255,137,213,72,41,
  199.   205,248,5,72,139,1,72,137,4,41,131,193,8,68,57,252,249,15,133,244,5,248,6,
  200.   141,67,1,248,7,139,92,36,28,137,68,36,4,49,201,252,247,195,237,15,132,244,
  201.   14,252,233,244,15,248,8,137,222,137,252,239,232,251,1,17,248,9,139,12,36,
  202.   68,137,185,233,137,222,137,252,239,232,251,1,0,139,28,36,139,149,233,252,
  203.   233,244,4,248,93,255,139,108,36,24,72,252,247,133,233,237,15,132,244,70,137,
  204.   149,233,141,68,194,252,248,137,133,233,49,192,72,137,133,233,176,235,136,
  205.   133,233,252,233,244,17,248,94,139,90,252,252,221,90,252,248,252,233,244,73,
  206.   248,95,129,252,248,239,15,130,244,70,129,122,253,4,239,15,133,244,248,255,
  207.   139,42,131,252,253,0,15,137,244,78,252,247,221,15,136,244,247,248,96,248,
  208.   78,139,90,252,252,199,66,252,252,237,137,106,252,248,252,233,244,73,248,1,
  209.   139,90,252,252,199,66,252,252,0,0,224,65,199,66,252,248,0,0,0,0,252,233,244,
  210.   73,248,2,15,135,244,70,252,242,15,16,2,72,184,237,237,102,72,15,110,200,15,
  211.   84,193,248,79,139,90,252,252,252,242,15,17,66,252,248,248,73,184,237,248,
  212.   84,255,137,68,36,4,248,71,252,247,195,237,15,133,244,253,248,5,56,67,252,
  213.   255,15,135,244,252,15,182,75,252,253,72,252,247,209,141,20,202,139,3,15,182,
  214.   204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,6,199,68,194,
  215.   252,244,237,131,192,1,252,233,244,5,248,7,72,199,193,252,248,252,255,252,
  216.   255,252,255,252,233,244,15,248,97,129,122,253,4,239,15,133,244,247,139,42,
  217.   252,233,244,78,248,1,255,15,135,244,70,252,242,15,16,2,232,244,98,252,242,
  218.   15,44,232,129,252,253,0,0,0,128,15,133,244,78,252,242,15,42,205,102,15,46,
  219.   193,15,138,244,79,15,132,244,78,252,233,244,79,248,99,129,122,253,4,239,15,
  220.   133,244,247,139,42,252,233,244,78,248,1,15,135,244,70,255,252,242,15,16,2,
  221.   232,244,100,252,242,15,44,232,129,252,253,0,0,0,128,15,133,244,78,252,242,
  222.   15,42,205,102,15,46,193,15,138,244,79,15,132,244,78,252,233,244,79,248,101,
  223.   129,252,248,239,15,130,244,70,129,122,253,4,239,15,131,244,70,252,242,15,
  224.   81,2,252,233,244,79,248,102,255,129,252,248,239,15,133,244,70,129,122,253,
  225.   4,239,15,131,244,70,252,242,15,16,2,137,213,232,251,1,18,137,252,234,252,
  226.   233,244,79,248,103,129,252,248,239,15,130,244,70,129,122,253,4,239,15,131,
  227.   244,70,252,242,15,16,2,137,213,232,251,1,19,137,252,234,252,233,244,79,248,
  228.   104,129,252,248,239,15,130,244,70,255,129,122,253,4,239,15,131,244,70,252,
  229.   242,15,16,2,137,213,232,251,1,20,137,252,234,252,233,244,79,248,105,129,252,
  230.   248,239,15,130,244,70,129,122,253,4,239,15,131,244,70,252,242,15,16,2,137,
  231.   213,232,251,1,21,137,252,234,252,233,244,79,248,106,129,252,248,239,15,130,
  232.   244,70,129,122,253,4,239,15,131,244,70,255,252,242,15,16,2,137,213,232,251,
  233.   1,22,137,252,234,252,233,244,79,248,107,129,252,248,239,15,130,244,70,129,
  234.   122,253,4,239,15,131,244,70,252,242,15,16,2,137,213,232,251,1,23,137,252,
  235.   234,252,233,244,79,248,108,129,252,248,239,15,130,244,70,129,122,253,4,239,
  236.   15,131,244,70,252,242,15,16,2,137,213,232,251,1,24,137,252,234,252,233,244,
  237.   79,248,109,255,129,252,248,239,15,130,244,70,129,122,253,4,239,15,131,244,
  238.   70,252,242,15,16,2,137,213,232,251,1,25,137,252,234,252,233,244,79,248,110,
  239.   129,252,248,239,15,130,244,70,129,122,253,4,239,15,131,244,70,252,242,15,
  240.   16,2,137,213,232,251,1,26,137,252,234,252,233,244,79,248,111,129,252,248,
  241.   239,15,130,244,70,255,129,122,253,4,239,15,131,244,70,252,242,15,16,2,137,
  242.   213,232,251,1,27,137,252,234,252,233,244,79,248,112,129,252,248,239,15,130,
  243.   244,70,129,122,253,4,239,15,131,244,70,252,242,15,16,2,137,213,232,251,1,
  244.   28,137,252,234,252,233,244,79,248,113,129,252,248,239,15,130,244,70,129,122,
  245.   253,4,239,15,131,244,70,255,252,242,15,16,2,137,213,232,251,1,29,137,252,
  246.   234,252,233,244,79,248,114,129,252,248,239,15,130,244,70,129,122,253,4,239,
  247.   15,131,244,70,129,122,253,12,239,15,131,244,70,252,242,15,16,2,252,242,15,
  248.   16,74,8,137,213,232,251,1,30,137,252,234,252,233,244,79,248,115,129,252,248,
  249.   239,15,130,244,70,129,122,253,4,239,15,131,244,70,255,129,122,253,12,239,
  250.   15,131,244,70,252,242,15,16,2,252,242,15,16,74,8,137,213,232,251,1,31,137,
  251.   252,234,252,233,244,79,248,116,129,252,248,239,15,130,244,70,129,122,253,
  252.   4,239,15,131,244,70,129,122,253,12,239,15,131,244,70,252,242,15,16,2,252,
  253.   242,15,16,74,8,137,213,232,251,1,32,137,252,234,252,233,244,79,248,117,129,
  254.   252,248,239,15,130,244,70,255,129,122,253,4,239,15,131,244,70,129,122,253,
  255.   12,239,15,131,244,70,221,66,8,221,2,217,252,253,221,217,252,233,244,94,248,
  256.   118,129,252,248,239,15,130,244,70,139,106,4,129,252,253,239,15,131,244,70,
  257.   139,90,252,252,139,2,137,106,252,252,137,66,252,248,209,229,129,252,253,0,
  258.   0,224,252,255,15,131,244,249,9,232,15,132,244,249,184,252,254,3,0,0,129,252,
  259.   253,0,0,32,0,15,130,244,250,248,1,255,193,252,237,21,41,197,252,242,15,42,
  260.   197,139,106,252,252,129,229,252,255,252,255,15,128,129,205,0,0,224,63,137,
  261.   106,252,252,248,2,252,242,15,17,2,184,237,252,233,244,84,248,3,15,87,192,
  262.   252,233,244,2,248,4,252,242,15,16,2,72,189,237,237,102,72,15,110,205,252,
  263.   242,15,89,193,252,242,15,17,66,252,248,139,106,252,252,184,52,4,0,0,209,229,
  264.   252,233,244,1,248,119,129,252,248,239,15,130,244,70,129,122,253,4,239,15,
  265.   131,244,70,252,242,15,16,2,139,106,4,139,90,252,252,209,229,129,252,253,0,
  266.   0,224,252,255,15,132,244,250,255,15,40,224,232,244,120,252,242,15,92,224,
  267.   248,1,252,242,15,17,66,252,248,252,242,15,17,34,139,66,252,252,139,106,4,
  268.   49,232,15,136,244,249,248,2,184,237,252,233,244,84,248,3,129,252,245,0,0,
  269.   0,128,137,106,4,252,233,244,2,248,4,15,87,228,252,233,244,1,248,121,185,2,
  270.   0,0,0,129,122,253,4,239,15,133,244,250,139,42,248,1,255,57,193,15,131,244,
  271.   78,129,124,253,202,252,252,239,15,133,244,249,59,108,202,252,248,15,79,108,
  272.   202,252,248,131,193,1,252,233,244,1,248,3,15,135,244,70,252,242,15,42,197,
  273.   252,233,244,252,248,4,15,135,244,70,252,242,15,16,2,248,5,57,193,15,131,244,
  274.   79,129,124,253,202,252,252,239,15,130,244,252,255,15,135,244,70,252,242,15,
  275.   42,76,202,252,248,252,233,244,253,248,6,252,242,15,16,76,202,252,248,248,
  276.   7,252,242,15,93,193,131,193,1,252,233,244,5,248,122,185,2,0,0,0,129,122,253,
  277.   4,239,15,133,244,250,139,42,248,1,57,193,15,131,244,78,129,124,253,202,252,
  278.   252,239,15,133,244,249,59,108,202,252,248,15,76,108,202,252,248,131,193,1,
  279.   252,233,244,1,248,3,255,15,135,244,70,252,242,15,42,197,252,233,244,252,248,
  280.   4,15,135,244,70,252,242,15,16,2,248,5,57,193,15,131,244,79,129,124,253,202,
  281.   252,252,239,15,130,244,252,15,135,244,70,252,242,15,42,76,202,252,248,252,
  282.   233,244,253,248,6,252,242,15,16,76,202,252,248,248,7,252,242,15,95,193,131,
  283.   193,1,252,233,244,5,248,123,255,129,252,248,239,15,133,244,70,129,122,253,
  284.   4,239,15,133,244,70,139,42,139,90,252,252,131,189,233,1,15,130,244,87,15,
  285.   182,173,233,252,233,244,78,248,124,65,139,174,233,65,59,174,233,15,130,244,
  286.   247,232,244,81,248,1,255,129,252,248,239,15,133,244,70,129,122,253,4,239,
  287.   15,133,244,70,139,42,129,252,253,252,255,0,0,0,15,135,244,70,137,108,36,4,
  288.   199,68,36,8,1,0,0,0,72,141,68,36,4,248,125,139,108,36,24,137,149,233,139,
  289.   84,36,8,72,137,198,137,252,239,137,92,36,28,232,251,1,33,248,126,139,149,
  290.   233,139,90,252,252,199,66,252,252,237,137,66,252,248,252,233,244,73,248,127,
  291.   65,139,174,233,65,59,174,233,15,130,244,247,255,232,244,81,248,1,199,68,36,
  292.   4,252,255,252,255,252,255,252,255,129,252,248,239,15,130,244,70,15,134,244,
  293.   247,129,122,253,20,239,15,133,244,70,139,106,16,137,108,36,4,248,1,129,122,
  294.   253,4,239,15,133,244,70,129,122,253,12,239,15,133,244,70,139,42,137,108,36,
  295.   8,139,173,233,139,74,8,139,68,36,4,57,197,15,130,244,251,248,2,255,133,201,
  296.   15,142,244,253,248,3,139,108,36,8,41,200,15,140,244,128,141,172,253,13,233,
  297.   131,192,1,248,4,137,68,36,8,137,232,252,233,244,125,248,5,15,140,244,252,
  298.   141,68,40,1,252,233,244,2,248,6,137,232,252,233,244,2,248,7,15,132,244,254,
  299.   255,1,252,233,131,193,1,15,143,244,3,248,8,185,1,0,0,0,252,233,244,3,248,
  300.   128,49,192,252,233,244,4,248,129,129,252,248,239,15,130,244,70,65,139,174,
  301.   233,65,59,174,233,15,130,244,247,232,244,81,248,1,129,122,253,4,239,255,15,
  302.   133,244,70,139,108,36,24,65,141,190,233,137,149,233,139,50,139,135,233,137,
  303.   175,233,137,135,233,137,92,36,28,232,251,1,34,137,199,232,251,1,35,252,233,
  304.   244,126,248,130,129,252,248,239,15,130,244,70,65,139,174,233,65,59,174,233,
  305.   15,130,244,247,232,244,81,248,1,255,129,122,253,4,239,15,133,244,70,139,108,
  306.   36,24,65,141,190,233,137,149,233,139,50,139,135,233,137,175,233,137,135,233,
  307.   137,92,36,28,232,251,1,36,137,199,232,251,1,35,252,233,244,126,248,131,129,
  308.   252,248,239,15,130,244,70,65,139,174,233,65,59,174,233,15,130,244,247,232,
  309.   244,81,248,1,255,129,122,253,4,239,15,133,244,70,139,108,36,24,65,141,190,
  310.   233,137,149,233,139,50,139,135,233,137,175,233,137,135,233,137,92,36,28,232,
  311.   251,1,37,137,199,232,251,1,35,252,233,244,126,248,132,129,252,248,239,15,
  312.   130,244,70,129,122,253,4,239,15,133,244,247,139,42,252,233,244,96,248,1,255,
  313.   15,135,244,70,252,242,15,16,2,72,189,237,237,102,72,15,110,205,252,242,15,
  314.   88,193,102,15,126,197,248,2,252,233,244,96,248,133,129,252,248,239,15,130,
  315.   244,70,72,189,237,237,102,72,15,110,205,129,122,253,4,239,15,133,244,247,
  316.   139,42,252,233,244,248,248,1,15,135,244,70,255,252,242,15,16,2,252,242,15,
  317.   88,193,102,15,126,197,248,2,137,68,36,4,141,68,194,252,240,248,1,57,208,15,
  318.   134,244,96,129,120,253,4,239,15,133,244,248,35,40,131,232,8,252,233,244,1,
  319.   248,2,15,135,244,134,252,242,15,16,0,252,242,15,88,193,102,15,126,193,33,
  320.   205,131,232,8,252,233,244,1,248,135,129,252,248,239,15,130,244,70,72,189,
  321.   237,237,255,102,72,15,110,205,129,122,253,4,239,15,133,244,247,139,42,252,
  322.   233,244,248,248,1,15,135,244,70,252,242,15,16,2,252,242,15,88,193,102,15,
  323.   126,197,248,2,137,68,36,4,141,68,194,252,240,248,1,57,208,15,134,244,96,129,
  324.   120,253,4,239,15,133,244,248,11,40,131,232,8,252,233,244,1,248,2,15,135,244,
  325.   134,255,252,242,15,16,0,252,242,15,88,193,102,15,126,193,9,205,131,232,8,
  326.   252,233,244,1,248,136,129,252,248,239,15,130,244,70,72,189,237,237,102,72,
  327.   15,110,205,129,122,253,4,239,15,133,244,247,139,42,252,233,244,248,248,1,
  328.   15,135,244,70,252,242,15,16,2,252,242,15,88,193,102,15,126,197,248,2,137,
  329.   68,36,4,141,68,194,252,240,248,1,57,208,15,134,244,96,255,129,120,253,4,239,
  330.   15,133,244,248,51,40,131,232,8,252,233,244,1,248,2,15,135,244,134,252,242,
  331.   15,16,0,252,242,15,88,193,102,15,126,193,49,205,131,232,8,252,233,244,1,248,
  332.   137,129,252,248,239,15,130,244,70,129,122,253,4,239,15,133,244,247,139,42,
  333.   252,233,244,248,248,1,255,15,135,244,70,252,242,15,16,2,72,189,237,237,102,
  334.   72,15,110,205,252,242,15,88,193,102,15,126,197,248,2,15,205,252,233,244,96,
  335.   248,138,129,252,248,239,15,130,244,70,129,122,253,4,239,15,133,244,247,139,
  336.   42,252,233,244,248,248,1,15,135,244,70,252,242,15,16,2,72,189,237,237,255,
  337.   102,72,15,110,205,252,242,15,88,193,102,15,126,197,248,2,252,247,213,252,
  338.   233,244,96,248,134,139,68,36,4,252,233,244,70,248,139,129,252,248,239,15,
  339.   130,244,70,129,122,253,4,239,15,133,244,247,139,42,252,233,244,248,248,1,
  340.   15,135,244,70,252,242,15,16,2,72,189,237,237,255,102,72,15,110,205,252,242,
  341.   15,88,193,102,15,126,197,248,2,129,122,253,12,239,15,133,244,70,139,74,8,
  342.   211,229,252,233,244,96,248,140,129,252,248,239,15,130,244,70,129,122,253,
  343.   4,239,15,133,244,247,139,42,252,233,244,248,248,1,15,135,244,70,252,242,15,
  344.   16,2,72,189,237,237,255,102,72,15,110,205,252,242,15,88,193,102,15,126,197,
  345.   248,2,129,122,253,12,239,15,133,244,70,139,74,8,211,252,237,252,233,244,96,
  346.   248,141,129,252,248,239,15,130,244,70,129,122,253,4,239,15,133,244,247,139,
  347.   42,252,233,244,248,248,1,15,135,244,70,252,242,15,16,2,72,189,237,237,255,
  348.   102,72,15,110,205,252,242,15,88,193,102,15,126,197,248,2,129,122,253,12,239,
  349.   15,133,244,70,139,74,8,211,252,253,252,233,244,96,248,142,129,252,248,239,
  350.   15,130,244,70,129,122,253,4,239,15,133,244,247,139,42,252,233,244,248,248,
  351.   1,15,135,244,70,252,242,15,16,2,72,189,237,237,255,102,72,15,110,205,252,
  352.   242,15,88,193,102,15,126,197,248,2,129,122,253,12,239,15,133,244,70,139,74,
  353.   8,211,197,252,233,244,96,248,143,129,252,248,239,15,130,244,70,129,122,253,
  354.   4,239,15,133,244,247,139,42,252,233,244,248,248,1,15,135,244,70,252,242,15,
  355.   16,2,72,189,237,237,255,102,72,15,110,205,252,242,15,88,193,102,15,126,197,
  356.   248,2,129,122,253,12,239,15,133,244,70,139,74,8,211,205,252,233,244,96,248,
  357.   144,184,237,252,233,244,70,248,145,184,237,248,70,139,108,36,24,139,90,252,
  358.   252,137,92,36,28,137,149,233,141,68,194,252,248,141,136,233,137,133,233,139,
  359.   66,252,248,59,141,233,15,135,244,251,137,252,239,252,255,144,233,255,139,
  360.   149,233,133,192,15,143,244,84,248,1,139,141,233,41,209,193,252,233,3,133,
  361.   192,141,65,1,139,106,252,248,15,133,244,34,139,157,233,139,11,15,182,252,
  362.   233,15,182,205,131,195,4,65,252,255,36,252,238,248,34,137,209,252,247,195,
  363.   237,15,133,244,249,15,182,107,252,253,72,252,247,213,141,20,252,234,252,233,
  364.   244,29,248,3,137,221,131,229,252,248,41,252,234,252,233,244,29,248,5,190,
  365.   237,137,252,239,232,251,1,0,139,149,233,255,49,192,252,233,244,1,248,81,93,
  366.   72,137,108,36,8,139,108,36,24,137,92,36,28,137,149,233,141,68,194,252,248,
  367.   137,252,239,137,133,233,232,251,1,38,139,149,233,139,133,233,41,208,193,232,
  368.   3,131,192,1,72,139,108,36,8,85,195,248,146,65,15,182,134,233,168,235,15,133,
  369.   244,251,168,235,15,133,244,247,168,235,15,132,244,247,65,252,255,142,233,
  370.   252,233,244,247,248,147,255,65,15,182,134,233,168,235,15,133,244,251,252,
  371.   233,244,247,248,148,65,15,182,134,233,168,235,15,133,244,251,168,235,15,132,
  372.   244,251,65,252,255,142,233,15,132,244,247,168,235,15,132,244,251,248,1,255,
  373.   139,108,36,24,137,149,233,137,222,137,252,239,232,251,1,39,248,3,139,149,
  374.   233,248,4,15,182,75,252,253,248,5,15,182,107,252,252,15,183,67,252,254,65,
  375.   252,255,164,253,252,238,233,248,149,131,195,4,139,77,232,137,76,36,4,252,
  376.   233,244,4,248,150,139,106,252,248,139,173,233,15,182,133,233,141,4,194,139,
  377.   108,36,24,137,149,233,137,133,233,137,222,65,141,190,233,73,137,174,233,137,
  378.   92,36,28,232,251,1,40,252,233,244,3,248,151,137,92,36,28,252,233,244,247,
  379.   248,152,255,137,92,36,28,131,203,1,248,1,141,68,194,252,248,139,108,36,24,
  380.   137,149,233,137,133,233,137,222,137,252,239,232,251,1,41,199,68,36,28,0,0,
  381.   0,0,131,227,252,254,139,149,233,72,137,193,139,133,233,41,208,72,137,205,
  382.   15,182,75,252,253,193,232,3,131,192,1,252,255,229,248,153,139,77,232,137,
  383.   12,36,68,137,116,36,8,68,139,116,36,4,15,182,75,252,253,141,12,202,65,131,
  384.   252,238,1,15,132,244,248,248,1,72,139,40,72,137,41,131,192,8,131,193,8,65,
  385.   131,252,238,1,15,133,244,1,248,2,15,182,67,252,253,15,182,107,252,255,1,232,
  386.   141,68,194,252,248,248,3,57,200,15,135,244,255,68,139,116,36,8,139,44,36,
  387.   65,139,142,233,139,4,169,133,192,15,132,244,47,15,183,128,233,57,232,15,132,
  388.   244,47,255,133,192,15,133,245,65,137,174,233,139,108,36,24,137,149,233,137,
  389.   222,65,141,190,233,73,137,174,233,232,251,1,42,139,149,233,252,233,244,47,
  390.   248,9,199,65,4,237,131,193,8,252,233,244,3,248,154,255,139,108,36,24,137,
  391.   149,233,137,222,137,252,239,232,251,1,43,139,149,233,131,252,235,4,252,233,
  392.   244,47,255,248,155,65,85,65,84,65,83,65,82,65,81,65,80,87,86,85,72,141,108,
  393.   36,88,85,83,82,81,80,15,182,69,252,248,138,101,252,240,76,137,125,252,248,
  394.   76,137,117,252,240,68,139,117,0,65,139,142,233,65,199,134,233,237,65,137,
  395.   134,233,65,137,142,233,72,129,252,236,239,72,131,197,128,252,242,68,15,17,
  396.   125,252,248,252,242,68,15,17,117,252,240,252,242,68,15,17,109,232,252,242,
  397.   68,15,17,101,224,252,242,68,15,17,93,216,252,242,68,15,17,85,208,252,242,
  398.   68,15,17,77,200,252,242,68,15,17,69,192,252,242,15,17,125,184,252,242,15,
  399.   17,117,176,252,242,15,17,109,168,252,242,15,17,101,160,252,242,15,17,93,152,
  400.   252,242,15,17,85,144,252,242,15,17,77,136,252,242,15,17,69,128,65,139,174,
  401.   233,65,139,150,233,73,137,174,233,137,149,233,72,137,230,65,141,190,233,65,
  402.   199,134,233,0,0,0,0,232,251,1,44,72,139,141,233,72,129,225,239,72,137,204,
  403.   137,169,233,139,149,233,139,153,233,252,233,244,247,248,156,255,72,131,196,
  404.   16,248,1,76,139,108,36,8,76,139,36,36,255,139,124,36,24,137,151,233,137,197,
  405.   137,28,36,137,218,65,139,182,233,232,251,1,45,139,28,36,137,232,139,108,36,
  406.   24,139,149,233,255,133,192,15,136,244,255,139,108,36,24,137,68,36,4,68,139,
  407.   122,252,248,69,139,191,233,69,139,191,233,137,149,233,65,199,134,233,0,0,
  408.   0,0,65,199,134,233,237,139,3,15,182,204,15,182,232,131,195,4,193,232,16,129,
  409.   252,253,239,15,130,244,249,129,252,253,239,15,131,244,250,248,2,139,68,36,
  410.   4,248,3,65,252,255,36,252,238,248,4,139,66,252,252,169,237,15,133,244,2,255,
  411.   15,182,64,252,253,72,252,247,208,68,139,124,194,252,248,69,139,191,233,69,
  412.   139,191,233,252,233,244,2,248,9,252,247,216,137,252,239,137,198,232,251,1,
  413.   1,248,157,248,98,72,184,237,237,102,72,15,110,208,72,184,237,237,102,72,15,
  414.   110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,247,102,15,85,208,
  415.   252,242,15,88,203,252,242,15,92,203,102,15,86,202,72,184,237,237,102,72,15,
  416.   110,208,252,242,15,194,193,1,102,15,84,194,252,242,15,92,200,15,40,193,248,
  417.   1,195,248,158,248,100,72,184,237,237,255,102,72,15,110,208,72,184,237,237,
  418.   102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,247,102,
  419.   15,85,208,252,242,15,88,203,252,242,15,92,203,102,15,86,202,72,184,237,237,
  420.   102,72,15,110,208,252,242,15,194,193,6,102,15,84,194,252,242,15,92,200,15,
  421.   40,193,248,1,195,248,159,248,120,72,184,237,237,102,72,15,110,208,72,184,
  422.   237,237,102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,
  423.   247,102,15,85,208,15,40,193,252,242,15,88,203,252,242,15,92,203,72,184,237,
  424.   237,102,72,15,110,216,252,242,15,194,193,1,102,15,84,195,252,242,15,92,200,
  425.   102,15,86,202,15,40,193,248,1,195,248,160,15,40,232,252,242,15,94,193,72,
  426.   184,237,237,255,102,72,15,110,208,72,184,237,237,102,72,15,110,216,15,40,
  427.   224,102,15,84,226,102,15,46,220,15,134,244,247,102,15,85,208,252,242,15,88,
  428.   227,252,242,15,92,227,102,15,86,226,72,184,237,237,102,72,15,110,208,252,
  429.   242,15,194,196,1,102,15,84,194,252,242,15,92,224,15,40,197,252,242,15,89,
  430.   204,252,242,15,92,193,195,248,1,252,242,15,89,200,15,40,197,252,242,15,92,
  431.   193,195,248,161,131,252,248,1,15,142,244,252,248,1,169,1,0,0,0,15,133,244,
  432.   248,252,242,15,89,192,209,232,252,233,244,1,248,2,209,232,15,132,244,251,
  433.   15,40,200,248,3,252,242,15,89,192,209,232,15,132,244,250,255,15,131,244,3,
  434.   252,242,15,89,200,252,233,244,3,248,4,252,242,15,89,193,248,5,195,248,6,15,
  435.   132,244,5,15,130,244,253,252,247,216,232,244,1,72,184,237,237,102,72,15,110,
  436.   200,252,242,15,94,200,15,40,193,195,248,7,72,184,237,237,102,72,15,110,192,
  437.   195,248,162,137,252,248,83,15,162,137,6,137,94,4,137,78,8,137,86,12,91,195,
  438.   248,163,255,204,255,204,248,164,83,65,87,65,86,72,131,252,236,40,68,141,181,
  439.   233,139,157,233,15,183,192,137,131,233,72,137,187,233,72,137,179,233,72,137,
  440.   147,233,72,137,139,233,252,242,15,17,131,233,252,242,15,17,139,233,252,242,
  441.   15,17,147,233,252,242,15,17,155,233,72,141,132,253,36,233,76,137,131,233,
  442.   76,137,139,233,252,242,15,17,163,233,252,242,15,17,171,233,252,242,15,17,
  443.   179,233,252,242,15,17,187,233,72,137,131,233,255,72,137,230,137,92,36,28,
  444.   137,223,232,251,1,46,65,199,134,233,237,139,144,233,139,128,233,41,208,139,
  445.   106,252,248,193,232,3,131,192,1,139,157,233,139,11,15,182,252,233,15,182,
  446.   205,131,195,4,65,252,255,36,252,238,248,33,139,76,36,24,65,139,158,233,72,
  447.   137,139,233,137,145,233,137,169,233,137,223,137,198,232,251,1,47,72,139,131,
  448.   233,252,242,15,16,131,233,252,233,244,17,248,165,85,72,137,229,83,72,137,
  449.   252,251,139,131,233,72,41,196,15,182,139,233,131,252,233,1,15,136,244,248,
  450.   248,1,255,72,139,132,253,203,233,72,137,132,253,204,233,131,252,233,1,15,
  451.   137,244,1,248,2,15,182,131,233,72,139,187,233,72,139,179,233,72,139,147,233,
  452.   72,139,139,233,76,139,131,233,76,139,139,233,133,192,15,132,244,251,15,40,
  453.   131,233,15,40,139,233,15,40,147,233,15,40,155,233,131,252,248,4,15,134,244,
  454.   251,255,15,40,163,233,15,40,171,233,15,40,179,233,15,40,187,233,248,5,252,
  455.   255,147,233,72,137,131,233,15,41,131,233,72,137,147,233,15,41,139,233,72,
  456.   139,93,252,248,201,195,255,249,255,129,124,253,202,4,239,15,133,244,253,129,
  457.   124,253,194,4,239,15,133,244,254,139,44,202,131,195,4,59,44,194,255,15,141,
  458.   244,255,255,15,140,244,255,255,15,143,244,255,255,15,142,244,255,255,248,
  459.   6,15,183,67,252,254,141,156,253,131,233,248,9,139,3,15,182,204,15,182,232,
  460.   131,195,4,193,232,16,65,252,255,36,252,238,248,7,15,135,244,50,129,124,253,
  461.   194,4,239,15,130,244,247,15,133,244,50,252,242,15,42,4,194,252,233,244,248,
  462.   248,8,15,135,244,50,252,242,15,42,12,202,252,242,15,16,4,194,131,195,4,102,
  463.   15,46,193,255,15,134,244,9,255,15,135,244,9,255,15,130,244,9,255,15,131,244,
  464.   9,255,252,233,244,6,248,1,252,242,15,16,4,194,248,2,131,195,4,102,15,46,4,
  465.   202,248,3,255,252,233,244,6,255,139,108,194,4,131,195,4,129,252,253,239,15,
  466.   133,244,253,129,124,253,202,4,239,15,133,244,254,139,44,194,59,44,202,255,
  467.   15,133,244,255,255,15,132,244,255,255,15,183,67,252,254,141,156,253,131,233,
  468.   248,9,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
  469.   238,248,7,15,135,244,251,129,124,253,202,4,239,15,130,244,247,15,133,244,
  470.   251,252,242,15,42,4,202,252,233,244,248,248,8,15,135,244,251,252,242,15,42,
  471.   4,194,102,15,46,4,202,252,233,244,250,248,1,252,242,15,16,4,202,248,2,102,
  472.   15,46,4,194,248,4,255,15,138,244,248,15,133,244,248,255,15,138,244,248,15,
  473.   132,244,247,255,248,1,15,183,67,252,254,141,156,253,131,233,248,2,255,248,
  474.   2,15,183,67,252,254,141,156,253,131,233,248,1,255,252,233,244,9,255,139,3,
  475.   15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,248,
  476.   5,129,252,253,239,15,132,244,55,129,124,253,202,4,239,15,132,244,55,57,108,
  477.   202,4,15,133,244,2,129,252,253,239,15,131,244,1,139,12,202,139,4,194,57,193,
  478.   15,132,244,1,129,252,253,239,15,135,244,2,129,252,253,239,15,130,244,2,255,
  479.   139,169,233,133,252,237,15,132,244,2,252,246,133,233,235,15,133,244,2,255,
  480.   49,252,237,255,189,1,0,0,0,255,252,233,244,54,255,248,3,129,252,253,239,255,
  481.   15,133,244,9,255,252,233,244,55,255,72,252,247,208,139,108,202,4,131,195,
  482.   4,129,252,253,239,15,133,244,249,139,12,202,65,59,12,135,255,139,108,202,
  483.   4,131,195,4,129,252,253,239,15,133,244,253,65,129,124,253,199,4,239,15,133,
  484.   244,254,65,139,44,199,59,44,202,255,15,183,67,252,254,141,156,253,131,233,
  485.   248,9,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
  486.   238,248,7,15,135,244,249,65,129,124,253,199,4,239,15,130,244,247,252,242,
  487.   65,15,42,4,199,252,233,244,248,248,8,252,242,15,42,4,202,102,65,15,46,4,199,
  488.   252,233,244,250,248,1,252,242,65,15,16,4,199,248,2,102,15,46,4,202,248,4,
  489.   255,72,252,247,208,139,108,202,4,131,195,4,57,197,255,15,133,244,249,15,183,
  490.   67,252,254,141,156,253,131,233,248,2,139,3,15,182,204,15,182,232,131,195,
  491.   4,193,232,16,65,252,255,36,252,238,248,3,129,252,253,239,15,133,244,2,252,
  492.   233,244,55,255,15,132,244,248,129,252,253,239,15,132,244,55,15,183,67,252,
  493.   254,141,156,253,131,233,248,2,139,3,15,182,204,15,182,232,131,195,4,193,232,
  494.   16,65,252,255,36,252,238,255,139,108,194,4,131,195,4,129,252,253,239,255,
  495.   15,131,244,247,255,137,108,202,4,139,44,194,137,44,202,255,15,183,67,252,
  496.   254,141,156,253,131,233,248,1,139,3,15,182,204,15,182,232,131,195,4,193,232,
  497.   16,65,252,255,36,252,238,255,3,68,202,4,15,133,244,56,139,3,15,182,204,15,
  498.   182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,129,124,253,202,4,
  499.   239,15,131,244,56,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
  500.   255,36,252,238,255,72,139,44,194,72,137,44,202,139,3,15,182,204,15,182,232,
  501.   131,195,4,193,232,16,65,252,255,36,252,238,255,49,252,237,129,124,253,194,
  502.   4,239,129,213,239,137,108,202,4,139,3,15,182,204,15,182,232,131,195,4,193,
  503.   232,16,65,252,255,36,252,238,255,129,124,253,194,4,239,15,133,244,251,139,
  504.   44,194,252,247,221,15,128,244,250,199,68,202,4,237,137,44,202,248,9,139,3,
  505.   15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,4,199,
  506.   68,202,4,0,0,224,65,199,4,202,0,0,0,0,252,233,244,9,248,5,15,135,244,61,252,
  507.   242,15,16,4,194,72,184,237,237,102,72,15,110,200,15,87,193,252,242,15,17,
  508.   4,202,252,233,244,9,255,129,124,253,194,4,239,15,133,244,248,139,4,194,139,
  509.   128,233,248,1,199,68,202,4,237,137,4,202,139,3,15,182,204,15,182,232,131,
  510.   195,4,193,232,16,65,252,255,36,252,238,248,2,129,124,253,194,4,239,15,133,
  511.   244,64,139,60,194,255,139,175,233,131,252,253,0,15,133,244,255,248,3,255,
  512.   248,65,137,213,232,251,1,48,137,252,234,15,182,75,252,253,252,233,244,1,255,
  513.   248,9,252,246,133,233,235,15,133,244,3,252,233,244,64,255,15,182,252,236,
  514.   15,182,192,255,129,124,253,252,234,4,239,15,133,244,58,65,129,124,253,199,
  515.   4,239,15,133,244,58,139,44,252,234,65,3,44,199,15,128,244,57,255,129,124,
  516.   253,252,234,4,239,15,133,244,60,65,129,124,253,199,4,239,15,133,244,60,65,
  517.   139,4,199,3,4,252,234,15,128,244,59,255,129,124,253,252,234,4,239,15,133,
  518.   244,63,129,124,253,194,4,239,15,133,244,63,139,44,252,234,3,44,194,15,128,
  519.   244,62,255,199,68,202,4,237,255,137,4,202,255,129,124,253,252,234,4,239,15,
  520.   133,244,58,65,129,124,253,199,4,239,15,133,244,58,139,44,252,234,65,43,44,
  521.   199,15,128,244,57,255,129,124,253,252,234,4,239,15,133,244,60,65,129,124,
  522.   253,199,4,239,15,133,244,60,65,139,4,199,43,4,252,234,15,128,244,59,255,129,
  523.   124,253,252,234,4,239,15,133,244,63,129,124,253,194,4,239,15,133,244,63,139,
  524.   44,252,234,43,44,194,15,128,244,62,255,129,124,253,252,234,4,239,15,133,244,
  525.   58,65,129,124,253,199,4,239,15,133,244,58,139,44,252,234,65,15,175,44,199,
  526.   15,128,244,57,255,129,124,253,252,234,4,239,15,133,244,60,65,129,124,253,
  527.   199,4,239,15,133,244,60,65,139,4,199,15,175,4,252,234,15,128,244,59,255,129,
  528.   124,253,252,234,4,239,15,133,244,63,129,124,253,194,4,239,15,133,244,63,139,
  529.   44,252,234,15,175,44,194,15,128,244,62,255,129,124,253,252,234,4,239,15,131,
  530.   244,58,65,129,124,253,199,4,239,15,131,244,58,252,242,15,16,4,252,234,252,
  531.   242,65,15,94,4,199,255,129,124,253,252,234,4,239,15,131,244,60,65,129,124,
  532.   253,199,4,239,15,131,244,60,252,242,65,15,16,4,199,252,242,15,94,4,252,234,
  533.   255,129,124,253,252,234,4,239,15,131,244,63,129,124,253,194,4,239,15,131,
  534.   244,63,252,242,15,16,4,252,234,252,242,15,94,4,194,255,252,242,15,17,4,202,
  535.   139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,
  536.   129,124,253,252,234,4,239,15,131,244,58,65,129,124,253,199,4,239,15,131,244,
  537.   58,252,242,15,16,4,252,234,252,242,65,15,16,12,199,255,129,124,253,252,234,
  538.   4,239,15,131,244,60,65,129,124,253,199,4,239,15,131,244,60,252,242,65,15,
  539.   16,4,199,252,242,15,16,12,252,234,255,129,124,253,252,234,4,239,15,131,244,
  540.   63,129,124,253,194,4,239,15,131,244,63,252,242,15,16,4,252,234,252,242,15,
  541.   16,12,194,255,248,166,232,244,160,252,242,15,17,4,202,139,3,15,182,204,15,
  542.   182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,252,233,244,166,255,
  543.   137,213,232,251,1,30,15,182,75,252,253,137,252,234,252,242,15,17,4,202,139,
  544.   3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,15,
  545.   182,252,236,15,182,192,139,124,36,24,137,151,233,141,52,194,137,194,41,252,
  546.   234,248,37,137,252,253,137,92,36,28,232,251,1,49,139,149,233,133,192,15,133,
  547.   244,51,15,182,107,252,255,15,182,75,252,253,72,139,4,252,234,72,137,4,202,
  548.   139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,
  549.   72,252,247,208,65,139,4,135,199,68,202,4,237,137,4,202,139,3,15,182,204,15,
  550.   182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,15,191,192,199,68,
  551.   202,4,237,137,4,202,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
  552.   255,36,252,238,255,252,242,65,15,16,4,199,252,242,15,17,4,202,139,3,15,182,
  553.   204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,72,252,247,
  554.   208,137,68,202,4,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
  555.   255,36,252,238,255,141,76,202,12,141,68,194,4,189,237,137,105,252,248,248,
  556.   1,137,41,131,193,8,57,193,15,134,244,1,139,3,15,182,204,15,182,232,131,195,
  557.   4,193,232,16,65,252,255,36,252,238,255,139,106,252,248,139,172,253,133,233,
  558.   139,173,233,72,139,69,0,72,137,4,202,139,3,15,182,204,15,182,232,131,195,
  559.   4,193,232,16,65,252,255,36,252,238,255,139,106,252,248,139,172,253,141,233,
  560.   128,189,233,0,139,173,233,139,12,194,139,68,194,4,137,77,0,137,69,4,15,132,
  561.   244,247,252,246,133,233,235,15,133,244,248,248,1,139,3,15,182,204,15,182,
  562.   232,131,195,4,193,232,16,65,252,255,36,252,238,248,2,129,232,239,129,252,
  563.   248,239,15,134,244,1,252,246,129,233,235,15,132,244,1,137,252,238,137,213,
  564.   65,141,190,233,255,232,251,1,50,137,252,234,252,233,244,1,255,72,252,247,
  565.   208,139,106,252,248,139,172,253,141,233,65,139,12,135,139,133,233,137,8,199,
  566.   64,4,237,252,246,133,233,235,15,133,244,248,248,1,139,3,15,182,204,15,182,
  567.   232,131,195,4,193,232,16,65,252,255,36,252,238,248,2,252,246,129,233,235,
  568.   15,132,244,1,128,189,233,0,15,132,244,1,137,213,137,198,65,141,190,233,232,
  569.   251,1,50,137,252,234,252,233,244,1,255,139,106,252,248,252,242,65,15,16,4,
  570.   199,139,172,253,141,233,139,141,233,252,242,15,17,1,139,3,15,182,204,15,182,
  571.   232,131,195,4,193,232,16,65,252,255,36,252,238,255,72,252,247,208,139,106,
  572.   252,248,139,172,253,141,233,139,141,233,137,65,4,139,3,15,182,204,15,182,
  573.   232,131,195,4,193,232,16,65,252,255,36,252,238,255,141,156,253,131,233,139,
  574.   108,36,24,131,189,233,0,15,132,244,247,137,149,233,141,52,202,137,252,239,
  575.   232,251,1,51,139,149,233,248,1,139,3,15,182,204,15,182,232,131,195,4,193,
  576.   232,16,65,252,255,36,252,238,255,72,252,247,208,139,108,36,24,137,149,233,
  577.   139,82,252,248,65,139,52,135,137,252,239,137,92,36,28,232,251,1,52,139,149,
  578.   233,15,182,75,252,253,137,4,202,199,68,202,4,237,139,3,15,182,204,15,182,
  579.   232,131,195,4,193,232,16,65,252,255,36,252,238,255,139,108,36,24,137,149,
  580.   233,65,139,142,233,65,59,142,233,137,92,36,28,15,131,244,251,248,1,137,194,
  581.   37,252,255,7,0,0,193,252,234,11,61,252,255,7,0,0,15,132,244,249,248,2,137,
  582.   252,239,137,198,232,251,1,53,139,149,233,15,182,75,252,253,137,4,202,199,
  583.   68,202,4,237,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,
  584.   36,252,238,248,3,184,1,8,0,0,252,233,244,2,248,5,137,252,239,232,251,1,54,
  585.   15,183,67,252,254,252,233,244,1,255,72,252,247,208,139,108,36,24,65,139,142,
  586.   233,137,92,36,28,65,59,142,233,137,149,233,15,131,244,249,248,2,65,139,52,
  587.   135,137,252,239,232,251,1,55,139,149,233,15,182,75,252,253,137,4,202,199,
  588.   68,202,4,237,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,
  589.   36,252,238,248,3,137,252,239,232,251,1,54,15,183,67,252,254,72,252,247,208,
  590.   252,233,244,2,255,72,252,247,208,139,106,252,248,139,173,233,65,139,4,135,
  591.   252,233,244,167,255,72,252,247,208,139,106,252,248,139,173,233,65,139,4,135,
  592.   252,233,244,168,255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,
  593.   133,244,40,139,44,252,234,129,124,253,194,4,239,15,133,244,251,139,4,194,
  594.   59,133,233,15,131,244,40,193,224,3,3,133,233,129,120,253,4,239,15,132,244,
  595.   248,72,139,40,72,137,44,202,248,1,139,3,15,182,204,15,182,232,131,195,4,193,
  596.   232,16,65,252,255,36,252,238,248,2,131,189,233,0,15,132,244,249,139,141,233,
  597.   252,246,129,233,235,255,15,132,244,40,15,182,75,252,253,248,3,199,68,202,
  598.   4,237,252,233,244,1,248,5,129,124,253,194,4,239,15,133,244,40,139,4,194,252,
  599.   233,244,167,255,15,182,252,236,15,182,192,72,252,247,208,65,139,4,135,129,
  600.   124,253,252,234,4,239,15,133,244,38,139,44,252,234,248,167,139,141,233,35,
  601.   136,233,105,201,239,3,141,233,248,1,129,185,233,239,15,133,244,250,57,129,
  602.   233,15,133,244,250,129,121,253,4,239,15,132,244,251,15,182,67,252,253,72,
  603.   139,41,72,137,44,194,248,2,255,139,3,15,182,204,15,182,232,131,195,4,193,
  604.   232,16,65,252,255,36,252,238,248,3,15,182,67,252,253,199,68,194,4,237,252,
  605.   233,244,2,248,4,139,137,233,133,201,15,133,244,1,248,5,139,141,233,133,201,
  606.   15,132,244,3,252,246,129,233,235,15,133,244,3,252,233,244,38,255,15,182,252,
  607.   236,15,182,192,129,124,253,252,234,4,239,15,133,244,39,139,44,252,234,59,
  608.   133,233,15,131,244,39,193,224,3,3,133,233,129,120,253,4,239,15,132,244,248,
  609.   72,139,40,72,137,44,202,248,1,139,3,15,182,204,15,182,232,131,195,4,193,232,
  610.   16,65,252,255,36,252,238,248,2,131,189,233,0,15,132,244,249,139,141,233,252,
  611.   246,129,233,235,15,132,244,39,255,15,182,75,252,253,248,3,199,68,202,4,237,
  612.   252,233,244,1,255,15,182,252,236,15,182,192,139,44,252,234,139,4,194,59,133,
  613.   233,15,131,244,41,193,224,3,3,133,233,248,42,72,139,40,72,137,44,202,248,
  614.   43,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,
  615.   255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,46,139,
  616.   44,252,234,129,124,253,194,4,239,15,133,244,251,139,4,194,59,133,233,15,131,
  617.   244,46,193,224,3,3,133,233,129,120,253,4,239,15,132,244,249,248,1,252,246,
  618.   133,233,235,15,133,244,253,248,2,72,139,44,202,72,137,40,139,3,15,182,204,
  619.   15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,3,255,131,189,233,
  620.   0,15,132,244,1,139,141,233,252,246,129,233,235,15,132,244,46,15,182,75,252,
  621.   253,252,233,244,1,248,5,129,124,253,194,4,239,15,133,244,46,139,4,194,252,
  622.   233,244,168,248,7,128,165,233,235,65,139,142,233,255,65,137,174,233,137,141,
  623.   233,15,182,75,252,253,252,233,244,2,255,15,182,252,236,15,182,192,72,252,
  624.   247,208,65,139,4,135,129,124,253,252,234,4,239,15,133,244,44,139,44,252,234,
  625.   248,168,139,141,233,35,136,233,105,201,239,198,133,233,0,3,141,233,248,1,
  626.   129,185,233,239,15,133,244,251,57,129,233,15,133,244,251,129,121,253,4,239,
  627.   15,132,244,250,248,2,255,252,246,133,233,235,15,133,244,253,248,3,15,182,
  628.   67,252,253,72,139,44,194,72,137,41,139,3,15,182,204,15,182,232,131,195,4,
  629.   193,232,16,65,252,255,36,252,238,248,4,131,189,233,0,15,132,244,2,137,12,
  630.   36,139,141,233,252,246,129,233,235,15,132,244,44,139,12,36,252,233,244,2,
  631.   248,5,139,137,233,133,201,15,133,244,1,255,139,141,233,133,201,15,132,244,
  632.   252,252,246,129,233,235,15,132,244,44,248,6,137,4,36,199,68,36,4,237,137,
  633.   108,36,8,139,124,36,24,137,151,233,72,141,20,36,137,252,238,137,252,253,137,
  634.   92,36,28,232,251,1,56,139,149,233,139,108,36,8,137,193,252,233,244,2,248,
  635.   7,128,165,233,235,65,139,134,233,65,137,174,233,137,133,233,252,233,244,3,
  636.   255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,45,139,
  637.   44,252,234,59,133,233,15,131,244,45,193,224,3,3,133,233,129,120,253,4,239,
  638.   15,132,244,249,248,1,252,246,133,233,235,15,133,244,253,248,2,72,139,12,202,
  639.   72,137,8,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
  640.   238,248,3,131,189,233,0,15,132,244,1,255,139,141,233,252,246,129,233,235,
  641.   15,132,244,45,15,182,75,252,253,252,233,244,1,248,7,128,165,233,235,65,139,
  642.   142,233,65,137,174,233,137,141,233,15,182,75,252,253,252,233,244,2,255,15,
  643.   182,252,236,15,182,192,139,44,252,234,139,4,194,252,246,133,233,235,15,133,
  644.   244,253,248,2,59,133,233,15,131,244,48,193,224,3,3,133,233,248,49,72,139,
  645.   44,202,72,137,40,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
  646.   255,36,252,238,248,7,128,165,233,235,65,139,142,233,65,137,174,233,137,141,
  647.   233,15,182,75,252,253,252,233,244,2,255,68,137,60,36,69,139,60,199,248,1,
  648.   141,12,202,139,105,252,248,252,246,133,233,235,15,133,244,253,248,2,139,68,
  649.   36,4,131,232,1,15,132,244,250,68,1,252,248,59,133,233,15,135,244,251,68,41,
  650.   252,248,65,193,231,3,68,3,189,233,248,3,72,139,41,131,193,8,73,137,47,65,
  651.   131,199,8,131,232,1,15,133,244,3,248,4,68,139,60,36,139,3,15,182,204,15,182,
  652.   232,131,195,4,193,232,16,65,252,255,36,252,238,248,5,139,124,36,24,137,151,
  653.   233,137,252,238,137,194,137,252,253,137,92,36,28,232,251,1,57,139,149,233,
  654.   15,182,75,252,253,252,233,244,1,248,7,255,128,165,233,235,65,139,134,233,
  655.   65,137,174,233,137,133,233,252,233,244,2,255,3,68,36,4,255,129,124,253,202,
  656.   4,239,139,44,202,15,133,244,66,141,84,202,8,137,90,252,252,139,157,233,139,
  657.   11,15,182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,255,141,76,202,
  658.   8,65,137,215,139,105,252,248,129,121,253,252,252,239,15,133,244,30,248,67,
  659.   139,90,252,252,252,247,195,237,15,133,244,253,248,1,137,106,252,248,137,68,
  660.   36,4,131,232,1,15,132,244,249,248,2,72,139,41,131,193,8,73,137,47,65,131,
  661.   199,8,131,232,1,15,133,244,2,139,106,252,248,248,3,139,68,36,4,128,189,233,
  662.   1,15,135,244,251,248,4,139,157,233,139,11,15,182,252,233,15,182,205,131,195,
  663.   4,65,252,255,36,252,238,248,5,255,252,247,195,237,15,133,244,4,15,182,75,
  664.   252,253,72,252,247,209,68,139,124,202,252,248,69,139,191,233,69,139,191,233,
  665.   252,233,244,4,248,7,129,252,235,239,252,247,195,237,15,133,244,254,41,218,
  666.   65,137,215,139,90,252,252,252,233,244,1,248,8,129,195,239,252,233,244,1,255,
  667.   141,76,202,8,72,139,105,232,72,139,65,252,240,72,137,41,72,137,65,8,139,105,
  668.   224,139,65,228,137,105,252,248,137,65,252,252,129,252,248,239,184,237,15,
  669.   133,244,30,137,202,137,90,252,252,139,157,233,139,11,15,182,252,233,15,182,
  670.   205,131,195,4,65,252,255,36,252,238,255,68,137,60,36,68,137,116,36,4,139,
  671.   108,202,252,240,139,68,202,252,248,68,139,181,233,131,195,4,68,139,189,233,
  672.   248,1,68,57,252,240,15,131,244,251,65,129,124,253,199,4,239,15,132,244,250,
  673.   199,68,202,4,237,137,4,202,73,139,44,199,72,137,108,202,8,131,192,1,137,68,
  674.   202,252,248,248,2,15,183,67,252,254,141,156,253,131,233,248,3,68,139,116,
  675.   36,4,68,139,60,36,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
  676.   255,36,252,238,248,4,131,192,1,252,233,244,1,248,5,68,41,252,240,248,6,59,
  677.   133,233,15,135,244,3,255,68,105,252,248,239,68,3,189,233,65,129,191,233,239,
  678.   15,132,244,253,70,141,116,48,1,73,139,175,233,73,139,135,233,72,137,44,202,
  679.   72,137,68,202,8,68,137,116,202,252,248,252,233,244,2,248,7,131,192,1,252,
  680.   233,244,6,255,129,124,253,202,252,236,239,15,133,244,251,139,108,202,232,
  681.   129,124,253,202,252,244,239,15,133,244,251,129,124,253,202,252,252,239,15,
  682.   133,244,251,128,189,233,235,15,133,244,251,141,156,253,131,233,199,68,202,
  683.   252,248,0,0,0,0,199,68,202,252,252,252,255,127,252,254,252,255,248,1,139,
  684.   3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,5,
  685.   198,67,252,252,235,141,156,253,131,233,198,3,235,252,233,244,1,255,15,182,
  686.   252,236,15,182,192,68,137,60,36,68,141,188,253,194,233,141,12,202,68,43,122,
  687.   252,252,133,252,237,15,132,244,251,141,108,252,233,252,248,65,57,215,15,131,
  688.   244,248,248,1,73,139,71,252,248,65,131,199,8,72,137,1,131,193,8,57,252,233,
  689.   15,131,244,249,65,57,215,15,130,244,1,248,2,199,65,4,237,131,193,8,57,252,
  690.   233,15,130,244,2,248,3,68,139,60,36,139,3,15,182,204,15,182,232,131,195,4,
  691.   193,232,16,65,252,255,36,252,238,248,5,199,68,36,4,1,0,0,0,137,208,68,41,
  692.   252,248,15,134,244,3,137,197,193,252,237,3,131,197,1,137,108,36,4,139,108,
  693.   36,24,1,200,59,133,233,15,135,244,253,248,6,255,73,139,71,252,248,65,131,
  694.   199,8,72,137,1,131,193,8,65,57,215,15,130,244,6,252,233,244,3,248,7,137,149,
  695.   233,137,141,233,137,92,36,28,65,41,215,139,116,36,4,131,252,238,1,137,252,
  696.   239,232,251,1,0,139,149,233,139,141,233,65,1,215,252,233,244,6,255,193,225,
  697.   3,255,248,1,139,90,252,252,137,68,36,4,252,247,195,237,15,133,244,253,255,
  698.   248,14,65,137,215,131,232,1,15,132,244,249,248,2,73,139,44,15,73,137,111,
  699.   252,248,65,131,199,8,131,232,1,15,133,244,2,248,3,139,68,36,4,15,182,107,
  700.   252,255,248,5,57,197,15,135,244,252,255,72,139,44,10,72,137,106,252,248,255,
  701.   248,5,56,67,252,255,15,135,244,252,255,15,182,75,252,253,72,252,247,209,141,
  702.   20,202,68,139,122,252,248,69,139,191,233,69,139,191,233,139,3,15,182,204,
  703.   15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,6,255,65,199,71,
  704.   252,252,237,65,131,199,8,255,199,68,194,252,244,237,255,131,192,1,252,233,
  705.   244,5,248,7,141,171,233,252,247,197,237,15,133,244,15,41,252,234,255,1,252,
  706.   233,255,137,221,209,252,237,129,229,239,102,65,129,172,253,46,233,238,15,
  707.   130,244,150,255,141,12,202,255,129,121,253,4,239,15,133,244,255,255,129,121,
  708.   253,12,239,15,133,244,68,129,121,253,20,239,15,133,244,68,139,41,131,121,
  709.   16,0,15,140,244,251,255,129,121,253,12,239,15,133,244,163,129,121,253,20,
  710.   239,15,133,244,163,255,139,105,16,133,252,237,15,136,244,251,3,41,15,128,
  711.   244,247,137,41,255,59,105,8,199,65,28,237,137,105,24,255,15,142,244,253,248,
  712.   1,248,6,141,156,253,131,233,255,141,156,253,131,233,15,183,67,252,254,15,
  713.   142,245,248,1,248,6,255,15,143,244,253,248,6,141,156,253,131,233,248,1,255,
  714.   248,7,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
  715.   238,248,5,255,3,41,15,128,244,1,137,41,255,15,141,244,7,255,141,156,253,131,
  716.   233,15,183,67,252,254,15,141,245,255,15,140,244,7,255,252,233,244,6,248,9,
  717.   255,129,121,253,4,239,255,15,131,244,68,129,121,253,12,239,15,131,244,68,
  718.   255,129,121,253,12,239,15,131,244,163,129,121,253,20,239,15,131,244,163,255,
  719.   139,105,20,255,129,252,253,239,15,131,244,68,255,252,242,15,16,1,252,242,
  720.   15,16,73,8,255,252,242,15,88,65,16,252,242,15,17,1,133,252,237,15,136,244,
  721.   249,255,15,140,244,249,255,102,15,46,200,248,1,252,242,15,17,65,24,255,15,
  722.   131,244,7,255,141,156,253,131,233,15,183,67,252,254,15,131,245,255,15,130,
  723.   244,7,255,252,233,244,6,248,3,102,15,46,193,252,233,244,1,255,141,12,202,
  724.   139,105,4,129,252,253,239,15,132,244,247,255,137,105,252,252,139,41,137,105,
  725.   252,248,252,233,245,255,141,156,253,131,233,139,1,137,105,252,252,137,65,
  726.   252,248,255,139,108,36,24,137,149,233,137,4,36,137,218,137,198,137,252,239,
  727.   232,251,1,58,139,4,36,139,149,233,255,65,139,142,233,139,4,129,72,139,128,
  728.   233,139,108,36,24,65,137,150,233,65,137,174,233,76,137,36,36,76,137,108,36,
  729.   8,72,131,252,236,16,252,255,224,255,141,156,253,131,233,139,3,15,182,204,
  730.   15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,137,221,209,252,
  731.   237,129,229,239,102,65,129,172,253,46,233,238,15,130,244,152,255,68,139,187,
  732.   233,139,108,36,24,141,12,202,59,141,233,15,135,244,25,15,182,139,233,57,200,
  733.   15,134,244,249,248,2,255,15,183,67,252,254,252,233,245,255,248,3,199,68,194,
  734.   252,252,237,131,192,1,57,200,15,134,244,3,252,233,244,2,255,141,44,197,237,
  735.   141,4,194,68,139,122,252,248,137,104,252,252,68,137,120,252,248,139,108,36,
  736.   24,141,12,200,59,141,233,15,135,244,24,137,209,137,194,15,182,171,233,133,
  737.   252,237,15,132,244,248,248,1,131,193,8,57,209,15,131,244,249,68,139,121,252,
  738.   248,68,137,56,68,139,121,252,252,68,137,120,4,131,192,8,199,65,252,252,237,
  739.   131,252,237,1,15,133,244,1,248,2,255,68,139,187,233,139,3,15,182,204,15,182,
  740.   232,131,195,4,193,232,16,65,252,255,36,252,238,255,248,3,199,64,4,237,131,
  741.   192,8,131,252,237,1,15,133,244,3,252,233,244,2,255,139,106,252,248,76,139,
  742.   189,233,139,108,36,24,141,68,194,252,248,137,149,233,141,136,233,59,141,233,
  743.   137,133,233,255,137,252,239,255,76,137,252,254,137,252,239,255,15,135,244,
  744.   23,65,199,134,233,237,255,65,252,255,215,255,65,252,255,150,233,255,139,149,
  745.   233,65,137,174,233,65,199,134,233,237,141,12,194,252,247,217,3,141,233,139,
  746.   90,252,252,252,233,244,12,255,254,0
  747. };

  748. #line 13 "vm_x86.dasc"
  749. //|.globals GLOB_
  750. enum {
  751.   GLOB_vm_returnp,
  752.   GLOB_cont_dispatch,
  753.   GLOB_vm_returnc,
  754.   GLOB_vm_unwind_yield,
  755.   GLOB_BC_RET_Z,
  756.   GLOB_vm_return,
  757.   GLOB_vm_leave_cp,
  758.   GLOB_vm_leave_unw,
  759.   GLOB_vm_unwind_c_eh,
  760.   GLOB_vm_unwind_c,
  761.   GLOB_vm_unwind_rethrow,
  762.   GLOB_vm_unwind_ff,
  763.   GLOB_vm_unwind_ff_eh,
  764.   GLOB_vm_growstack_c,
  765.   GLOB_vm_growstack_v,
  766.   GLOB_vm_growstack_f,
  767.   GLOB_vm_resume,
  768.   GLOB_vm_pcall,
  769.   GLOB_vm_call,
  770.   GLOB_vm_call_dispatch,
  771.   GLOB_vmeta_call,
  772.   GLOB_vm_call_dispatch_f,
  773.   GLOB_vm_cpcall,
  774.   GLOB_cont_ffi_callback,
  775.   GLOB_vm_call_tail,
  776.   GLOB_cont_cat,
  777.   GLOB_cont_ra,
  778.   GLOB_BC_CAT_Z,
  779.   GLOB_vmeta_tgets,
  780.   GLOB_vmeta_tgetb,
  781.   GLOB_vmeta_tgetv,
  782.   GLOB_vmeta_tgetr,
  783.   GLOB_BC_TGETR_Z,
  784.   GLOB_BC_TGETR2_Z,
  785.   GLOB_vmeta_tsets,
  786.   GLOB_vmeta_tsetb,
  787.   GLOB_vmeta_tsetv,
  788.   GLOB_cont_nop,
  789.   GLOB_vmeta_tsetr,
  790.   GLOB_BC_TSETR_Z,
  791.   GLOB_vmeta_comp,
  792.   GLOB_vmeta_binop,
  793.   GLOB_cont_condt,
  794.   GLOB_cont_condf,
  795.   GLOB_vmeta_equal,
  796.   GLOB_vmeta_equal_cd,
  797.   GLOB_vmeta_istype,
  798.   GLOB_vmeta_arith_vno,
  799.   GLOB_vmeta_arith_vn,
  800.   GLOB_vmeta_arith_nvo,
  801.   GLOB_vmeta_arith_nv,
  802.   GLOB_vmeta_unm,
  803.   GLOB_vmeta_arith_vvo,
  804.   GLOB_vmeta_arith_vv,
  805.   GLOB_vmeta_len,
  806.   GLOB_BC_LEN_Z,
  807.   GLOB_vmeta_call_ra,
  808.   GLOB_BC_CALLT_Z,
  809.   GLOB_vmeta_for,
  810.   GLOB_ff_assert,
  811.   GLOB_fff_fallback,
  812.   GLOB_fff_res_,
  813.   GLOB_ff_type,
  814.   GLOB_fff_res1,
  815.   GLOB_ff_getmetatable,
  816.   GLOB_ff_setmetatable,
  817.   GLOB_ff_rawget,
  818.   GLOB_ff_tonumber,
  819.   GLOB_fff_resi,
  820.   GLOB_fff_resxmm0,
  821.   GLOB_ff_tostring,
  822.   GLOB_fff_gcstep,
  823.   GLOB_ff_next,
  824.   GLOB_fff_res2,
  825.   GLOB_fff_res,
  826.   GLOB_ff_pairs,
  827.   GLOB_ff_ipairs_aux,
  828.   GLOB_fff_res0,
  829.   GLOB_ff_ipairs,
  830.   GLOB_ff_pcall,
  831.   GLOB_ff_xpcall,
  832.   GLOB_ff_coroutine_resume,
  833.   GLOB_ff_coroutine_wrap_aux,
  834.   GLOB_ff_coroutine_yield,
  835.   GLOB_fff_resn,
  836.   GLOB_ff_math_abs,
  837.   GLOB_fff_resbit,
  838.   GLOB_ff_math_floor,
  839.   GLOB_vm_floor_sse,
  840.   GLOB_ff_math_ceil,
  841.   GLOB_vm_ceil_sse,
  842.   GLOB_ff_math_sqrt,
  843.   GLOB_ff_math_log,
  844.   GLOB_ff_math_log10,
  845.   GLOB_ff_math_exp,
  846.   GLOB_ff_math_sin,
  847.   GLOB_ff_math_cos,
  848.   GLOB_ff_math_tan,
  849.   GLOB_ff_math_asin,
  850.   GLOB_ff_math_acos,
  851.   GLOB_ff_math_atan,
  852.   GLOB_ff_math_sinh,
  853.   GLOB_ff_math_cosh,
  854.   GLOB_ff_math_tanh,
  855.   GLOB_ff_math_pow,
  856.   GLOB_ff_math_atan2,
  857.   GLOB_ff_math_fmod,
  858.   GLOB_ff_math_ldexp,
  859.   GLOB_ff_math_frexp,
  860.   GLOB_ff_math_modf,
  861.   GLOB_vm_trunc_sse,
  862.   GLOB_ff_math_min,
  863.   GLOB_ff_math_max,
  864.   GLOB_ff_string_byte,
  865.   GLOB_ff_string_char,
  866.   GLOB_fff_newstr,
  867.   GLOB_fff_resstr,
  868.   GLOB_ff_string_sub,
  869.   GLOB_fff_emptystr,
  870.   GLOB_ff_string_reverse,
  871.   GLOB_ff_string_lower,
  872.   GLOB_ff_string_upper,
  873.   GLOB_ff_bit_tobit,
  874.   GLOB_ff_bit_band,
  875.   GLOB_fff_fallback_bit_op,
  876.   GLOB_ff_bit_bor,
  877.   GLOB_ff_bit_bxor,
  878.   GLOB_ff_bit_bswap,
  879.   GLOB_ff_bit_bnot,
  880.   GLOB_ff_bit_lshift,
  881.   GLOB_ff_bit_rshift,
  882.   GLOB_ff_bit_arshift,
  883.   GLOB_ff_bit_rol,
  884.   GLOB_ff_bit_ror,
  885.   GLOB_fff_fallback_2,
  886.   GLOB_fff_fallback_1,
  887.   GLOB_vm_record,
  888.   GLOB_vm_rethook,
  889.   GLOB_vm_inshook,
  890.   GLOB_cont_hook,
  891.   GLOB_vm_hotloop,
  892.   GLOB_vm_callhook,
  893.   GLOB_vm_hotcall,
  894.   GLOB_cont_stitch,
  895.   GLOB_vm_profhook,
  896.   GLOB_vm_exit_handler,
  897.   GLOB_vm_exit_interp,
  898.   GLOB_vm_floor,
  899.   GLOB_vm_ceil,
  900.   GLOB_vm_trunc,
  901.   GLOB_vm_mod,
  902.   GLOB_vm_powi_sse,
  903.   GLOB_vm_cpuid,
  904.   GLOB_assert_bad_for_arg_type,
  905.   GLOB_vm_ffi_callback,
  906.   GLOB_vm_ffi_call,
  907.   GLOB_BC_MODVN_Z,
  908.   GLOB_BC_TGETS_Z,
  909.   GLOB_BC_TSETS_Z,
  910.   GLOB__MAX
  911. };
  912. #line 14 "vm_x86.dasc"
  913. //|.globalnames globnames
  914. static const char *const globnames[] = {
  915.   "vm_returnp",
  916.   "cont_dispatch",
  917.   "vm_returnc",
  918.   "vm_unwind_yield",
  919.   "BC_RET_Z",
  920.   "vm_return",
  921.   "vm_leave_cp",
  922.   "vm_leave_unw",
  923.   "vm_unwind_c_eh",
  924.   "vm_unwind_c@8",
  925.   "vm_unwind_rethrow",
  926.   "vm_unwind_ff@4",
  927.   "vm_unwind_ff_eh",
  928.   "vm_growstack_c",
  929.   "vm_growstack_v",
  930.   "vm_growstack_f",
  931.   "vm_resume",
  932.   "vm_pcall",
  933.   "vm_call",
  934.   "vm_call_dispatch",
  935.   "vmeta_call",
  936.   "vm_call_dispatch_f",
  937.   "vm_cpcall",
  938.   "cont_ffi_callback",
  939.   "vm_call_tail",
  940.   "cont_cat",
  941.   "cont_ra",
  942.   "BC_CAT_Z",
  943.   "vmeta_tgets",
  944.   "vmeta_tgetb",
  945.   "vmeta_tgetv",
  946.   "vmeta_tgetr",
  947.   "BC_TGETR_Z",
  948.   "BC_TGETR2_Z",
  949.   "vmeta_tsets",
  950.   "vmeta_tsetb",
  951.   "vmeta_tsetv",
  952.   "cont_nop",
  953.   "vmeta_tsetr",
  954.   "BC_TSETR_Z",
  955.   "vmeta_comp",
  956.   "vmeta_binop",
  957.   "cont_condt",
  958.   "cont_condf",
  959.   "vmeta_equal",
  960.   "vmeta_equal_cd",
  961.   "vmeta_istype",
  962.   "vmeta_arith_vno",
  963.   "vmeta_arith_vn",
  964.   "vmeta_arith_nvo",
  965.   "vmeta_arith_nv",
  966.   "vmeta_unm",
  967.   "vmeta_arith_vvo",
  968.   "vmeta_arith_vv",
  969.   "vmeta_len",
  970.   "BC_LEN_Z",
  971.   "vmeta_call_ra",
  972.   "BC_CALLT_Z",
  973.   "vmeta_for",
  974.   "ff_assert",
  975.   "fff_fallback",
  976.   "fff_res_",
  977.   "ff_type",
  978.   "fff_res1",
  979.   "ff_getmetatable",
  980.   "ff_setmetatable",
  981.   "ff_rawget",
  982.   "ff_tonumber",
  983.   "fff_resi",
  984.   "fff_resxmm0",
  985.   "ff_tostring",
  986.   "fff_gcstep",
  987.   "ff_next",
  988.   "fff_res2",
  989.   "fff_res",
  990.   "ff_pairs",
  991.   "ff_ipairs_aux",
  992.   "fff_res0",
  993.   "ff_ipairs",
  994.   "ff_pcall",
  995.   "ff_xpcall",
  996.   "ff_coroutine_resume",
  997.   "ff_coroutine_wrap_aux",
  998.   "ff_coroutine_yield",
  999.   "fff_resn",
  1000.   "ff_math_abs",
  1001.   "fff_resbit",
  1002.   "ff_math_floor",
  1003.   "vm_floor_sse",
  1004.   "ff_math_ceil",
  1005.   "vm_ceil_sse",
  1006.   "ff_math_sqrt",
  1007.   "ff_math_log",
  1008.   "ff_math_log10",
  1009.   "ff_math_exp",
  1010.   "ff_math_sin",
  1011.   "ff_math_cos",
  1012.   "ff_math_tan",
  1013.   "ff_math_asin",
  1014.   "ff_math_acos",
  1015.   "ff_math_atan",
  1016.   "ff_math_sinh",
  1017.   "ff_math_cosh",
  1018.   "ff_math_tanh",
  1019.   "ff_math_pow",
  1020.   "ff_math_atan2",
  1021.   "ff_math_fmod",
  1022.   "ff_math_ldexp",
  1023.   "ff_math_frexp",
  1024.   "ff_math_modf",
  1025.   "vm_trunc_sse",
  1026.   "ff_math_min",
  1027.   "ff_math_max",
  1028.   "ff_string_byte",
  1029.   "ff_string_char",
  1030.   "fff_newstr",
  1031.   "fff_resstr",
  1032.   "ff_string_sub",
  1033.   "fff_emptystr",
  1034.   "ff_string_reverse",
  1035.   "ff_string_lower",
  1036.   "ff_string_upper",
  1037.   "ff_bit_tobit",
  1038.   "ff_bit_band",
  1039.   "fff_fallback_bit_op",
  1040.   "ff_bit_bor",
  1041.   "ff_bit_bxor",
  1042.   "ff_bit_bswap",
  1043.   "ff_bit_bnot",
  1044.   "ff_bit_lshift",
  1045.   "ff_bit_rshift",
  1046.   "ff_bit_arshift",
  1047.   "ff_bit_rol",
  1048.   "ff_bit_ror",
  1049.   "fff_fallback_2",
  1050.   "fff_fallback_1",
  1051.   "vm_record",
  1052.   "vm_rethook",
  1053.   "vm_inshook",
  1054.   "cont_hook",
  1055.   "vm_hotloop",
  1056.   "vm_callhook",
  1057.   "vm_hotcall",
  1058.   "cont_stitch",
  1059.   "vm_profhook",
  1060.   "vm_exit_handler",
  1061.   "vm_exit_interp",
  1062.   "vm_floor",
  1063.   "vm_ceil",
  1064.   "vm_trunc",
  1065.   "vm_mod",
  1066.   "vm_powi_sse",
  1067.   "vm_cpuid",
  1068.   "assert_bad_for_arg_type",
  1069.   "vm_ffi_callback",
  1070.   "vm_ffi_call@4",
  1071.   "BC_MODVN_Z",
  1072.   "BC_TGETS_Z",
  1073.   "BC_TSETS_Z",
  1074.   (const char *)0
  1075. };
  1076. #line 15 "vm_x86.dasc"
  1077. //|.externnames extnames
  1078. static const char *const extnames[] = {
  1079.   "lj_state_growstack@8",
  1080.   "lj_err_throw@8",
  1081.   "lj_meta_tget",
  1082.   "lj_tab_getinth@8",
  1083.   "lj_meta_tset",
  1084.   "lj_tab_setinth",
  1085.   "lj_meta_comp",
  1086.   "lj_meta_equal",
  1087.   "lj_meta_equal_cd@8",
  1088.   "lj_meta_istype",
  1089.   "lj_meta_arith",
  1090.   "lj_meta_len@8",
  1091.   "lj_meta_call",
  1092.   "lj_meta_for@8",
  1093.   "lj_tab_get",
  1094.   "lj_strfmt_number@8",
  1095.   "lj_tab_next",
  1096.   "lj_ffh_coroutine_wrap_err@8",
  1097.   "log",
  1098.   "log10",
  1099.   "exp",
  1100.   "sin",
  1101.   "cos",
  1102.   "tan",
  1103.   "asin",
  1104.   "acos",
  1105.   "atan",
  1106.   "sinh",
  1107.   "cosh",
  1108.   "tanh",
  1109.   "pow",
  1110.   "atan2",
  1111.   "fmod",
  1112.   "lj_str_new",
  1113.   "lj_buf_putstr_reverse@8",
  1114.   "lj_buf_tostr@4",
  1115.   "lj_buf_putstr_lower@8",
  1116.   "lj_buf_putstr_upper@8",
  1117.   "lj_gc_step@4",
  1118.   "lj_dispatch_ins@8",
  1119.   "lj_trace_hot@8",
  1120.   "lj_dispatch_call@8",
  1121.   "lj_dispatch_stitch@8",
  1122.   "lj_dispatch_profile@8",
  1123.   "lj_trace_exit@8",
  1124.   "lj_log_trace_direct_exit@8",
  1125.   "lj_ccallback_enter@8",
  1126.   "lj_ccallback_leave@8",
  1127.   "lj_tab_len@4",
  1128.   "lj_meta_cat",
  1129.   "lj_gc_barrieruv@8",
  1130.   "lj_func_closeuv@8",
  1131.   "lj_func_newL_gc",
  1132.   "lj_tab_new",
  1133.   "lj_gc_step_fixtop@4",
  1134.   "lj_tab_dup@8",
  1135.   "lj_tab_newkey",
  1136.   "lj_tab_reasize",
  1137.   "lj_log_trace_entry@8",
  1138.   (const char *)0
  1139. };
  1140. #line 16 "vm_x86.dasc"
  1141. //|
  1142. //|//-----------------------------------------------------------------------
  1143. //|
  1144. //|.if P64
  1145. //|.define X64, 1
  1146. //|.if WIN
  1147. //|.define X64WIN, 1
  1148. //|.endif
  1149. //|.endif
  1150. //|
  1151. //|// Fixed register assignments for the interpreter.
  1152. //|// This is very fragile and has many dependencies. Caveat emptor.
  1153. //|.define BASE,                edx                // Not C callee-save, refetched anyway.
  1154. //|.if not X64
  1155. //|.define KBASE,                edi                // Must be C callee-save.
  1156. //|.define KBASEa,        KBASE
  1157. //|.define PC,                esi                // Must be C callee-save.
  1158. //|.define PCa,                PC
  1159. //|.define DISPATCH,        ebx                // Must be C callee-save.
  1160. //|.elif X64WIN
  1161. //|.define KBASE,                edi                // Must be C callee-save.
  1162. //|.define KBASEa,        rdi
  1163. //|.define PC,                esi                // Must be C callee-save.
  1164. //|.define PCa,                rsi
  1165. //|.define DISPATCH,        ebx                // Must be C callee-save.
  1166. //|.else
  1167. //|.define KBASE,                r15d                // Must be C callee-save.
  1168. //|.define KBASEa,        r15
  1169. //|.define PC,                ebx                // Must be C callee-save.
  1170. //|.define PCa,                rbx
  1171. //|.define DISPATCH,        r14d                // Must be C callee-save.
  1172. //|.endif
  1173. //|
  1174. //|.define RA,                ecx
  1175. //|.define RAH,                ch
  1176. //|.define RAL,                cl
  1177. //|.define RB,                ebp                // Must be ebp (C callee-save).
  1178. //|.define RC,                eax                // Must be eax.
  1179. //|.define RCW,                ax
  1180. //|.define RCH,                ah
  1181. //|.define RCL,                al
  1182. //|.define OP,                RB
  1183. //|.define RD,                RC
  1184. //|.define RDW,                RCW
  1185. //|.define RDL,                RCL
  1186. //|.if X64
  1187. //|.define RAa, rcx
  1188. //|.define RBa, rbp
  1189. //|.define RCa, rax
  1190. //|.define RDa, rax
  1191. //|.else
  1192. //|.define RAa, RA
  1193. //|.define RBa, RB
  1194. //|.define RCa, RC
  1195. //|.define RDa, RD
  1196. //|.endif
  1197. //|
  1198. //|.if not X64
  1199. //|.define FCARG1,        ecx                // x86 fastcall arguments.
  1200. //|.define FCARG2,        edx
  1201. //|.elif X64WIN
  1202. //|.define CARG1,                rcx                // x64/WIN64 C call arguments.
  1203. //|.define CARG2,                rdx
  1204. //|.define CARG3,                r8
  1205. //|.define CARG4,                r9
  1206. //|.define CARG1d,        ecx
  1207. //|.define CARG2d,        edx
  1208. //|.define CARG3d,        r8d
  1209. //|.define CARG4d,        r9d
  1210. //|.define FCARG1,        CARG1d                // Upwards compatible to x86 fastcall.
  1211. //|.define FCARG2,        CARG2d
  1212. //|.else
  1213. //|.define CARG1,                rdi                // x64/POSIX C call arguments.
  1214. //|.define CARG2,                rsi
  1215. //|.define CARG3,                rdx
  1216. //|.define CARG4,                rcx
  1217. //|.define CARG5,                r8
  1218. //|.define CARG6,                r9
  1219. //|.define CARG1d,        edi
  1220. //|.define CARG2d,        esi
  1221. //|.define CARG3d,        edx
  1222. //|.define CARG4d,        ecx
  1223. //|.define CARG5d,        r8d
  1224. //|.define CARG6d,        r9d
  1225. //|.define FCARG1,        CARG1d                // Simulate x86 fastcall.
  1226. //|.define FCARG2,        CARG2d
  1227. //|.endif
  1228. //|
  1229. //|// Type definitions. Some of these are only used for documentation.
  1230. //|.type L,                lua_State
  1231. #define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V)
  1232. #line 106 "vm_x86.dasc"
  1233. //|.type GL,                global_State
  1234. #define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V)
  1235. #line 107 "vm_x86.dasc"
  1236. //|.type TVALUE,                TValue
  1237. #define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V)
  1238. #line 108 "vm_x86.dasc"
  1239. //|.type GCOBJ,                GCobj
  1240. #define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V)
  1241. #line 109 "vm_x86.dasc"
  1242. //|.type STR,                GCstr
  1243. #define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V)
  1244. #line 110 "vm_x86.dasc"
  1245. //|.type TAB,                GCtab
  1246. #define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V)
  1247. #line 111 "vm_x86.dasc"
  1248. //|.type LFUNC,                GCfuncL
  1249. #define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V)
  1250. #line 112 "vm_x86.dasc"
  1251. //|.type CFUNC,                GCfuncC
  1252. #define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V)
  1253. #line 113 "vm_x86.dasc"
  1254. //|.type PROTO,                GCproto
  1255. #define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V)
  1256. #line 114 "vm_x86.dasc"
  1257. //|.type UPVAL,                GCupval
  1258. #define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V)
  1259. #line 115 "vm_x86.dasc"
  1260. //|.type NODE,                Node
  1261. #define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V)
  1262. #line 116 "vm_x86.dasc"
  1263. //|.type NARGS,                int
  1264. #define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V)
  1265. #line 117 "vm_x86.dasc"
  1266. //|.type TRACE,                GCtrace
  1267. #define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V)
  1268. #line 118 "vm_x86.dasc"
  1269. //|.type SBUF,                SBuf
  1270. #define DtE(_V) (int)(ptrdiff_t)&(((SBuf *)0)_V)
  1271. #line 119 "vm_x86.dasc"
  1272. //|
  1273. //|// Stack layout while in interpreter. Must match with lj_frame.h.
  1274. //|//-----------------------------------------------------------------------
  1275. //|.if not X64                // x86 stack layout.
  1276. //|
  1277. //|.define CFRAME_SPACE,        aword*7                        // Delta for esp (see <--).
  1278. //|.macro saveregs_
  1279. //|  push edi; push esi; push ebx
  1280. //|  sub esp, CFRAME_SPACE
  1281. //|.endmacro
  1282. //|.macro saveregs
  1283. //|  push ebp; saveregs_
  1284. //|.endmacro
  1285. //|.macro restoreregs
  1286. //|  add esp, CFRAME_SPACE
  1287. //|  pop ebx; pop esi; pop edi; pop ebp
  1288. //|.endmacro
  1289. //|
  1290. //|.define SAVE_ERRF,        aword [esp+aword*15]        // vm_pcall/vm_cpcall only.
  1291. //|.define SAVE_NRES,        aword [esp+aword*14]
  1292. //|.define SAVE_CFRAME,        aword [esp+aword*13]
  1293. //|.define SAVE_L,        aword [esp+aword*12]
  1294. //|//----- 16 byte aligned, ^^^ arguments from C caller
  1295. //|.define SAVE_RET,        aword [esp+aword*11]        //<-- esp entering interpreter.
  1296. //|.define SAVE_R4,        aword [esp+aword*10]
  1297. //|.define SAVE_R3,        aword [esp+aword*9]
  1298. //|.define SAVE_R2,        aword [esp+aword*8]
  1299. //|//----- 16 byte aligned
  1300. //|.define SAVE_R1,        aword [esp+aword*7]        //<-- esp after register saves.
  1301. //|.define SAVE_PC,        aword [esp+aword*6]
  1302. //|.define TMP2,                aword [esp+aword*5]
  1303. //|.define TMP1,                aword [esp+aword*4]
  1304. //|//----- 16 byte aligned
  1305. //|.define ARG4,                aword [esp+aword*3]
  1306. //|.define ARG3,                aword [esp+aword*2]
  1307. //|.define ARG2,                aword [esp+aword*1]
  1308. //|.define ARG1,                aword [esp]                //<-- esp while in interpreter.
  1309. //|//----- 16 byte aligned, ^^^ arguments for C callee
  1310. //|
  1311. //|// FPARGx overlaps ARGx and ARG(x+1) on x86.
  1312. //|.define FPARG3,        qword [esp+qword*1]
  1313. //|.define FPARG1,        qword [esp]
  1314. //|// TMPQ overlaps TMP1/TMP2. ARG5/MULTRES overlap TMP1/TMP2 (and TMPQ).
  1315. //|.define TMPQ,                qword [esp+aword*4]
  1316. //|.define TMP3,                ARG4
  1317. //|.define ARG5,                TMP1
  1318. //|.define TMPa,                TMP1
  1319. //|.define MULTRES,        TMP2
  1320. //|
  1321. //|// Arguments for vm_call and vm_pcall.
  1322. //|.define INARG_BASE,        SAVE_CFRAME                // Overwritten by SAVE_CFRAME!
  1323. //|
  1324. //|// Arguments for vm_cpcall.
  1325. //|.define INARG_CP_CALL,        SAVE_ERRF
  1326. //|.define INARG_CP_UD,        SAVE_NRES
  1327. //|.define INARG_CP_FUNC,        SAVE_CFRAME
  1328. //|
  1329. //|//-----------------------------------------------------------------------
  1330. //|.elif X64WIN                // x64/Windows stack layout
  1331. //|
  1332. //|.define CFRAME_SPACE,        aword*5                        // Delta for rsp (see <--).
  1333. //|.macro saveregs_
  1334. //|  push rdi; push rsi; push rbx
  1335. //|  sub rsp, CFRAME_SPACE
  1336. //|.endmacro
  1337. //|.macro saveregs
  1338. //|  push rbp; saveregs_
  1339. //|.endmacro
  1340. //|.macro restoreregs
  1341. //|  add rsp, CFRAME_SPACE
  1342. //|  pop rbx; pop rsi; pop rdi; pop rbp
  1343. //|.endmacro
  1344. //|
  1345. //|.define SAVE_CFRAME,        aword [rsp+aword*13]
  1346. //|.define SAVE_PC,        dword [rsp+dword*25]
  1347. //|.define SAVE_L,        dword [rsp+dword*24]
  1348. //|.define SAVE_ERRF,        dword [rsp+dword*23]
  1349. //|.define SAVE_NRES,        dword [rsp+dword*22]
  1350. //|.define TMP2,                dword [rsp+dword*21]
  1351. //|.define TMP1,                dword [rsp+dword*20]
  1352. //|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by interpreter
  1353. //|.define SAVE_RET,        aword [rsp+aword*9]        //<-- rsp entering interpreter.
  1354. //|.define SAVE_R4,        aword [rsp+aword*8]
  1355. //|.define SAVE_R3,        aword [rsp+aword*7]
  1356. //|.define SAVE_R2,        aword [rsp+aword*6]
  1357. //|.define SAVE_R1,        aword [rsp+aword*5]        //<-- rsp after register saves.
  1358. //|.define ARG5,                aword [rsp+aword*4]
  1359. //|.define CSAVE_4,        aword [rsp+aword*3]
  1360. //|.define CSAVE_3,        aword [rsp+aword*2]
  1361. //|.define CSAVE_2,        aword [rsp+aword*1]
  1362. //|.define CSAVE_1,        aword [rsp]                //<-- rsp while in interpreter.
  1363. //|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by callee
  1364. //|
  1365. //|// TMPQ overlaps TMP1/TMP2. MULTRES overlaps TMP2 (and TMPQ).
  1366. //|.define TMPQ,                qword [rsp+aword*10]
  1367. //|.define MULTRES,        TMP2
  1368. //|.define TMPa,                ARG5
  1369. //|.define ARG5d,                dword [rsp+aword*4]
  1370. //|.define TMP3,                ARG5d
  1371. //|
  1372. //|//-----------------------------------------------------------------------
  1373. //|.else                        // x64/POSIX stack layout
  1374. //|
  1375. //|.define CFRAME_SPACE,        aword*5                        // Delta for rsp (see <--).
  1376. //|.macro saveregs_
  1377. //|  push rbx; push r15; push r14
  1378. //|  sub rsp, CFRAME_SPACE
  1379. //|.endmacro
  1380. //|.macro saveregs
  1381. //|  push rbp; saveregs_
  1382. //|.endmacro
  1383. //|.macro restoreregs
  1384. //|  add rsp, CFRAME_SPACE
  1385. //|  pop r14; pop r15; pop rbx; pop rbp
  1386. //|.endmacro
  1387. //|
  1388. //|//----- 16 byte aligned,
  1389. //|.define SAVE_RET,        aword [rsp+aword*9]        //<-- rsp entering interpreter.
  1390. //|.define SAVE_R4,        aword [rsp+aword*8]
  1391. //|.define SAVE_R3,        aword [rsp+aword*7]
  1392. //|.define SAVE_R2,        aword [rsp+aword*6]
  1393. //|.define SAVE_R1,        aword [rsp+aword*5]        //<-- rsp after register saves.
  1394. //|.define SAVE_CFRAME,        aword [rsp+aword*4]
  1395. //|.define SAVE_PC,        dword [rsp+dword*7]
  1396. //|.define SAVE_L,        dword [rsp+dword*6]
  1397. //|.define SAVE_ERRF,        dword [rsp+dword*5]
  1398. //|.define SAVE_NRES,        dword [rsp+dword*4]
  1399. //|.define TMPa,                aword [rsp+aword*1]
  1400. //|.define TMP2,                dword [rsp+dword*1]
  1401. //|.define TMP1,                dword [rsp]                //<-- rsp while in interpreter.
  1402. //|//----- 16 byte aligned
  1403. //|
  1404. //|// TMPQ overlaps TMP1/TMP2. MULTRES overlaps TMP2 (and TMPQ).
  1405. //|.define TMPQ,                qword [rsp]
  1406. //|.define TMP3,                dword [rsp+aword*1]
  1407. //|.define MULTRES,        TMP2
  1408. //|
  1409. //|.endif
  1410. //|
  1411. //|//-----------------------------------------------------------------------
  1412. //|
  1413. //|// Instruction headers.
  1414. //|.macro ins_A; .endmacro
  1415. //|.macro ins_AD; .endmacro
  1416. //|.macro ins_AJ; .endmacro
  1417. //|.macro ins_ABC; movzx RB, RCH; movzx RC, RCL; .endmacro
  1418. //|.macro ins_AB_; movzx RB, RCH; .endmacro
  1419. //|.macro ins_A_C; movzx RC, RCL; .endmacro
  1420. //|.macro ins_AND; not RDa; .endmacro
  1421. //|
  1422. //|// Instruction decode+dispatch. Carefully tuned (nope, lodsd is not faster).
  1423. //|.macro ins_NEXT
  1424. //|  mov RC, [PC]
  1425. //|  movzx RA, RCH
  1426. //|  movzx OP, RCL
  1427. //|  add PC, 4
  1428. //|  shr RC, 16
  1429. //|.if X64
  1430. //|  jmp aword [DISPATCH+OP*8]
  1431. //|.else
  1432. //|  jmp aword [DISPATCH+OP*4]
  1433. //|.endif
  1434. //|.endmacro
  1435. //|
  1436. //|// Instruction footer.
  1437. //|.if 1
  1438. //|  // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
  1439. //|  .define ins_next, ins_NEXT
  1440. //|  .define ins_next_, ins_NEXT
  1441. //|.else
  1442. //|  // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
  1443. //|  // Affects only certain kinds of benchmarks (and only with -j off).
  1444. //|  // Around 10%-30% slower on Core2, a lot more slower on P4.
  1445. //|  .macro ins_next
  1446. //|    jmp ->ins_next
  1447. //|  .endmacro
  1448. //|  .macro ins_next_
  1449. //|  ->ins_next:
  1450. //|    ins_NEXT
  1451. //|  .endmacro
  1452. //|.endif
  1453. //|
  1454. //|// Call decode and dispatch.
  1455. //|.macro ins_callt
  1456. //|  // BASE = new base, RB = LFUNC, RD = nargs+1, [BASE-4] = PC
  1457. //|  mov PC, LFUNC:RB->pc
  1458. //|  mov RA, [PC]
  1459. //|  movzx OP, RAL
  1460. //|  movzx RA, RAH
  1461. //|  add PC, 4
  1462. //|.if X64
  1463. //|  jmp aword [DISPATCH+OP*8]
  1464. //|.else
  1465. //|  jmp aword [DISPATCH+OP*4]
  1466. //|.endif
  1467. //|.endmacro
  1468. //|
  1469. //|.macro ins_call
  1470. //|  // BASE = new base, RB = LFUNC, RD = nargs+1
  1471. //|  mov [BASE-4], PC
  1472. //|  ins_callt
  1473. //|.endmacro
  1474. //|
  1475. //|//-----------------------------------------------------------------------
  1476. //|
  1477. //|// Macros to test operand types.
  1478. //|.macro checktp, reg, tp;  cmp dword [BASE+reg*8+4], tp; .endmacro
  1479. //|.macro checknum, reg, target; checktp reg, LJ_TISNUM; jae target; .endmacro
  1480. //|.macro checkint, reg, target; checktp reg, LJ_TISNUM; jne target; .endmacro
  1481. //|.macro checkstr, reg, target; checktp reg, LJ_TSTR; jne target; .endmacro
  1482. //|.macro checktab, reg, target; checktp reg, LJ_TTAB; jne target; .endmacro
  1483. //|
  1484. //|// These operands must be used with movzx.
  1485. //|.define PC_OP, byte [PC-4]
  1486. //|.define PC_RA, byte [PC-3]
  1487. //|.define PC_RB, byte [PC-1]
  1488. //|.define PC_RC, byte [PC-2]
  1489. //|.define PC_RD, word [PC-2]
  1490. //|
  1491. //|.macro branchPC, reg
  1492. //|  lea PC, [PC+reg*4-BCBIAS_J*4]
  1493. //|.endmacro
  1494. //|
  1495. //|// Assumes DISPATCH is relative to GL.
  1496. #define DISPATCH_GL(field)        (GG_DISP2G + (int)offsetof(global_State, field))
  1497. #define DISPATCH_J(field)        (GG_DISP2J + (int)offsetof(jit_State, field))
  1498. //|
  1499. #define PC2PROTO(field)  ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
  1500. //|
  1501. //|// Decrement hashed hotcount and trigger trace recorder if zero.
  1502. //|.macro hotloop, reg
  1503. //|  mov reg, PC
  1504. //|  shr reg, 1
  1505. //|  and reg, HOTCOUNT_PCMASK
  1506. //|  sub word [DISPATCH+reg+GG_DISP2HOT], HOTCOUNT_LOOP
  1507. //|  jb ->vm_hotloop
  1508. //|.endmacro
  1509. //|
  1510. //|.macro hotcall, reg
  1511. //|  mov reg, PC
  1512. //|  shr reg, 1
  1513. //|  and reg, HOTCOUNT_PCMASK
  1514. //|  sub word [DISPATCH+reg+GG_DISP2HOT], HOTCOUNT_CALL
  1515. //|  jb ->vm_hotcall
  1516. //|.endmacro
  1517. //|
  1518. //|// Set current VM state.
  1519. //|.macro set_vmstate, st
  1520. //|  mov dword [DISPATCH+DISPATCH_GL(vmstate)], ~LJ_VMST_..st
  1521. //|.endmacro
  1522. //|
  1523. //|// x87 compares.
  1524. //|.macro fcomparepp                        // Compare and pop st0 >< st1.
  1525. //|  fucomip st1
  1526. //|  fpop
  1527. //|.endmacro
  1528. //|
  1529. //|.macro fpop1; fstp st1; .endmacro
  1530. //|
  1531. //|// Synthesize SSE FP constants.
  1532. //|.macro sseconst_abs, reg, tmp                // Synthesize abs mask.
  1533. //|.if X64
  1534. //|  mov64 tmp, U64x(7fffffff,ffffffff); movd reg, tmp
  1535. //|.else
  1536. //|  pxor reg, reg; pcmpeqd reg, reg; psrlq reg, 1
  1537. //|.endif
  1538. //|.endmacro
  1539. //|
  1540. //|.macro sseconst_hi, reg, tmp, val        // Synthesize hi-32 bit const.
  1541. //|.if X64
  1542. //|  mov64 tmp, U64x(val,00000000); movd reg, tmp
  1543. //|.else
  1544. //|  mov tmp, 0x .. val; movd reg, tmp; pshufd reg, reg, 0x51
  1545. //|.endif
  1546. //|.endmacro
  1547. //|
  1548. //|.macro sseconst_sign, reg, tmp                // Synthesize sign mask.
  1549. //|  sseconst_hi reg, tmp, 80000000
  1550. //|.endmacro
  1551. //|.macro sseconst_1, reg, tmp                // Synthesize 1.0.
  1552. //|  sseconst_hi reg, tmp, 3ff00000
  1553. //|.endmacro
  1554. //|.macro sseconst_m1, reg, tmp                // Synthesize -1.0.
  1555. //|  sseconst_hi reg, tmp, bff00000
  1556. //|.endmacro
  1557. //|.macro sseconst_2p52, reg, tmp                // Synthesize 2^52.
  1558. //|  sseconst_hi reg, tmp, 43300000
  1559. //|.endmacro
  1560. //|.macro sseconst_tobit, reg, tmp        // Synthesize 2^52 + 2^51.
  1561. //|  sseconst_hi reg, tmp, 43380000
  1562. //|.endmacro
  1563. //|
  1564. //|// Move table write barrier back. Overwrites reg.
  1565. //|.macro barrierback, tab, reg
  1566. //|  and byte tab->marked, (uint8_t)~LJ_GC_BLACK        // black2gray(tab)
  1567. //|  mov reg, [DISPATCH+DISPATCH_GL(gc.grayagain)]
  1568. //|  mov [DISPATCH+DISPATCH_GL(gc.grayagain)], tab
  1569. //|  mov tab->gclist, reg
  1570. //|.endmacro
  1571. //|
  1572. //|//-----------------------------------------------------------------------

  1573. /* Generate subroutines used by opcodes and other parts of the VM. */
  1574. /* The .code_sub section should be last to help static branch prediction. */
  1575. static void build_subroutines(BuildCtx *ctx)
  1576. {
  1577.   //|.code_sub
  1578.   dasm_put(Dst, 0);
  1579. #line 426 "vm_x86.dasc"
  1580.   //|
  1581.   //|//-----------------------------------------------------------------------
  1582.   //|//-- Return handling ----------------------------------------------------
  1583.   //|//-----------------------------------------------------------------------
  1584.   //|
  1585.   //|->vm_returnp:
  1586.   //|  test PC, FRAME_P
  1587.   //|  jz ->cont_dispatch
  1588.   //|
  1589.   //|  // Return from pcall or xpcall fast func.
  1590.   //|  and PC, -8
  1591.   //|  sub BASE, PC                        // Restore caller base.
  1592.   //|  lea RAa, [RA+PC-8]                        // Rebase RA and prepend one result.
  1593.   //|  mov PC, [BASE-4]                        // Fetch PC of previous frame.
  1594.   //|  // Prepending may overwrite the pcall frame, so do it at the end.
  1595.   //|  mov dword [BASE+RA+4], LJ_TTRUE        // Prepend true to results.
  1596.   //|
  1597.   //|->vm_returnc:
  1598.   //|  add RD, 1                                // RD = nresults+1
  1599.   //|  jz ->vm_unwind_yield
  1600.   //|  mov MULTRES, RD
  1601.   //|  test PC, FRAME_TYPE
  1602.   //|  jz ->BC_RET_Z                        // Handle regular return to Lua.
  1603.   //|
  1604.   //|->vm_return:
  1605.   //|  // BASE = base, RA = resultofs, RD = nresults+1 (= MULTRES), PC = return
  1606.   //|  xor PC, FRAME_C
  1607.   //|  test PC, FRAME_TYPE
  1608.   //|  jnz ->vm_returnp
  1609.   //|
  1610.   //|  // Return to C.
  1611.   //|  set_vmstate C
  1612.   //|  and PC, -8
  1613.   //|  sub PC, BASE
  1614.   //|  neg PC                                // Previous base = BASE - delta.
  1615.   //|
  1616.   //|  sub RD, 1
  1617.   //|  jz >2
  1618.   //|1:  // Move results down.
  1619.   //|.if X64
  1620.   //|  mov RBa, [BASE+RA]
  1621.   dasm_put(Dst, 2, FRAME_P, LJ_TTRUE, FRAME_TYPE, FRAME_C, FRAME_TYPE, DISPATCH_GL(vmstate), ~LJ_VMST_C);
  1622. #line 467 "vm_x86.dasc"
  1623.   //|  mov [BASE-8], RBa
  1624.   //|.else
  1625.   //|  mov RB, [BASE+RA]
  1626.   //|  mov [BASE-8], RB
  1627.   //|  mov RB, [BASE+RA+4]
  1628.   //|  mov [BASE-4], RB
  1629.   //|.endif
  1630.   //|  add BASE, 8
  1631.   //|  sub RD, 1
  1632.   //|  jnz <1
  1633.   //|2:
  1634.   //|  mov L:RB, SAVE_L
  1635.   //|  mov L:RB->base, PC
  1636.   //|3:
  1637.   //|  mov RD, MULTRES
  1638.   //|  mov RA, SAVE_NRES                        // RA = wanted nresults+1
  1639.   //|4:
  1640.   //|  cmp RA, RD
  1641.   //|  jne >6                                // More/less results wanted?
  1642.   //|5:
  1643.   //|  sub BASE, 8
  1644.   //|  mov L:RB->top, BASE
  1645.   //|
  1646.   //|->vm_leave_cp:
  1647.   //|  mov RAa, SAVE_CFRAME                // Restore previous C frame.
  1648.   //|  mov L:RB->cframe, RAa
  1649.   //|  xor eax, eax                        // Ok return status for vm_pcall.
  1650.   //|
  1651.   //|->vm_leave_unw:
  1652.   //|  restoreregs
  1653.   //|  ret
  1654.   //|
  1655.   //|6:
  1656.   //|  jb >7                                // Less results wanted?
  1657.   //|  // More results wanted. Check stack size and fill up results with nil.
  1658.   //|  cmp BASE, L:RB->maxstack
  1659.   //|  ja >8
  1660.   //|  mov dword [BASE-4], LJ_TNIL
  1661.   //|  add BASE, 8
  1662.   dasm_put(Dst, 92, Dt1(->base), Dt1(->top), Dt1(->cframe), Dt1(->maxstack), LJ_TNIL);
  1663. #line 506 "vm_x86.dasc"
  1664.   //|  add RD, 1
  1665.   //|  jmp <4
  1666.   //|
  1667.   //|7:  // Less results wanted.
  1668.   //|  test RA, RA
  1669.   //|  jz <5                                // But check for LUA_MULTRET+1.
  1670.   //|  sub RA, RD                                // Negative result!
  1671.   //|  lea BASE, [BASE+RA*8]                // Correct top.
  1672.   //|  jmp <5
  1673.   //|
  1674.   //|8:  // Corner case: need to grow stack for filling up results.
  1675.   //|  // This can happen if:
  1676.   //|  // - A C function grows the stack (a lot).
  1677.   //|  // - The GC shrinks the stack in between.
  1678.   //|  // - A return back from a lua_call() with (high) nresults adjustment.
  1679.   //|  mov L:RB->top, BASE                // Save current top held in BASE (yes).
  1680.   //|  mov MULTRES, RD                        // Need to fill only remainder with nil.
  1681.   //|  mov FCARG2, RA
  1682.   //|  mov FCARG1, L:RB
  1683.   //|  call extern lj_state_growstack@8        // (lua_State *L, int n)
  1684.   //|  mov BASE, L:RB->top                // Need the (realloced) L->top in BASE.
  1685.   //|  jmp <3
  1686.   //|
  1687.   //|->vm_unwind_yield:
  1688.   //|  mov al, LUA_YIELD
  1689.   //|  jmp ->vm_unwind_c_eh
  1690.   //|
  1691.   //|->vm_unwind_c@8:                        // Unwind C stack, return from vm_pcall.
  1692.   //|  // (void *cframe, int errcode)
  1693.   //|.if X64
  1694.   //|  mov eax, CARG2d                        // Error return status for vm_pcall.
  1695.   //|  mov rsp, CARG1
  1696.   //|.else
  1697.   //|  mov eax, FCARG2                        // Error return status for vm_pcall.
  1698.   //|  mov esp, FCARG1
  1699.   //|.endif
  1700.   //|->vm_unwind_c_eh:                        // Landing pad for external unwinder.
  1701.   //|  mov L:RB, SAVE_L
  1702.   //|  mov GL:RB, L:RB->glref
  1703.   //|  mov dword GL:RB->vmstate, ~LJ_VMST_C
  1704.   //|  jmp ->vm_leave_unw
  1705.   dasm_put(Dst, 192, Dt1(->top), Dt1(->top), LUA_YIELD, Dt1(->glref), Dt2(->vmstate), ~LJ_VMST_C);
  1706. #line 547 "vm_x86.dasc"
  1707.   //|
  1708.   //|->vm_unwind_rethrow:
  1709.   //|.if X64 and not X64WIN
  1710.   //|  mov FCARG1, SAVE_L
  1711.   //|  mov FCARG2, eax
  1712.   //|  restoreregs
  1713.   //|  jmp extern lj_err_throw@8                // (lua_State *L, int errcode)
  1714.   //|.endif
  1715.   //|
  1716.   //|->vm_unwind_ff@4:                        // Unwind C stack, return from ff pcall.
  1717.   //|  // (void *cframe)
  1718.   //|.if X64
  1719.   //|  and CARG1, CFRAME_RAWMASK
  1720.   //|  mov rsp, CARG1
  1721.   //|.else
  1722.   //|  and FCARG1, CFRAME_RAWMASK
  1723.   //|  mov esp, FCARG1
  1724.   //|.endif
  1725.   //|->vm_unwind_ff_eh:                        // Landing pad for external unwinder.
  1726.   //|  mov L:RB, SAVE_L
  1727.   //|  mov RAa, -8                        // Results start at BASE+RA = BASE-8.
  1728.   //|  mov RD, 1+1                        // Really 1+2 results, incr. later.
  1729.   //|  mov BASE, L:RB->base
  1730.   //|  mov DISPATCH, L:RB->glref                // Setup pointer to dispatch table.
  1731.   //|  add DISPATCH, GG_G2DISP
  1732.   //|  mov PC, [BASE-4]                        // Fetch PC of previous frame.
  1733.   //|  mov dword [BASE-4], LJ_TFALSE        // Prepend false to error message.
  1734.   //|  set_vmstate INTERP
  1735.   //|  jmp ->vm_returnc                        // Increments RD/MULTRES and returns.
  1736.   //|
  1737.   //|//-----------------------------------------------------------------------
  1738.   //|//-- Grow stack for calls -----------------------------------------------
  1739.   //|//-----------------------------------------------------------------------
  1740.   //|
  1741.   //|->vm_growstack_c:                        // Grow stack for C function.
  1742.   //|  mov FCARG2, LUA_MINSTACK
  1743.   //|  jmp >2
  1744.   //|
  1745.   //|->vm_growstack_v:                        // Grow stack for vararg Lua function.
  1746.   //|  sub RD, 8
  1747.   dasm_put(Dst, 275, CFRAME_RAWMASK, 1+1, Dt1(->base), Dt1(->glref), GG_G2DISP, LJ_TFALSE, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, LUA_MINSTACK);
  1748. #line 587 "vm_x86.dasc"
  1749.   //|  jmp >1
  1750.   //|
  1751.   //|->vm_growstack_f:                        // Grow stack for fixarg Lua function.
  1752.   //|  // BASE = new base, RD = nargs+1, RB = L, PC = first PC
  1753.   //|  lea RD, [BASE+NARGS:RD*8-8]
  1754.   //|1:
  1755.   //|  movzx RA, byte [PC-4+PC2PROTO(framesize)]
  1756.   //|  add PC, 4                                // Must point after first instruction.
  1757.   //|  mov L:RB->base, BASE
  1758.   //|  mov L:RB->top, RD
  1759.   //|  mov SAVE_PC, PC
  1760.   //|  mov FCARG2, RA
  1761.   //|2:
  1762.   //|  // RB = L, L->base = new base, L->top = top
  1763.   //|  mov FCARG1, L:RB
  1764.   //|  call extern lj_state_growstack@8        // (lua_State *L, int n)
  1765.   //|  mov BASE, L:RB->base
  1766.   //|  mov RD, L:RB->top
  1767.   //|  mov LFUNC:RB, [BASE-8]
  1768.   //|  sub RD, BASE
  1769.   //|  shr RD, 3
  1770.   //|  add NARGS:RD, 1
  1771.   //|  // BASE = new base, RB = LFUNC, RD = nargs+1
  1772.   //|  ins_callt                                // Just retry the call.
  1773.   //|
  1774.   //|//-----------------------------------------------------------------------
  1775.   //|//-- Entry points into the assembler VM ---------------------------------
  1776.   //|//-----------------------------------------------------------------------
  1777.   //|
  1778.   //|->vm_resume:                                // Setup C frame and resume thread.
  1779.   //|  // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
  1780.   //|  saveregs
  1781.   //|.if X64
  1782.   //|  mov L:RB, CARG1d                        // Caveat: CARG1d may be RA.
  1783.   //|  mov SAVE_L, CARG1d
  1784.   //|  mov RA, CARG2d
  1785.   //|.else
  1786.   //|  mov L:RB, SAVE_L
  1787.   //|  mov RA, INARG_BASE                        // Caveat: overlaps SAVE_CFRAME!
  1788.   //|.endif
  1789.   //|  mov PC, FRAME_CP
  1790.   //|  xor RD, RD
  1791.   //|  lea KBASEa, [esp+CFRAME_RESUME]
  1792.   //|  mov DISPATCH, L:RB->glref                // Setup pointer to dispatch table.
  1793.   //|  add DISPATCH, GG_G2DISP
  1794.   //|  mov SAVE_PC, RD                        // Any value outside of bytecode is ok.
  1795.   //|  mov SAVE_CFRAME, RDa
  1796.   //|.if X64
  1797.   //|  mov SAVE_NRES, RD
  1798.   //|  mov SAVE_ERRF, RD
  1799.   //|.endif
  1800.   //|  mov L:RB->cframe, KBASEa
  1801.   //|  cmp byte L:RB->status, RDL
  1802.   //|  je >2                                // Initial resume (like a call).
  1803.   //|
  1804.   //|  // Resume after yield (like a return).
  1805.   //|  mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
  1806.   dasm_put(Dst, 371, -4+PC2PROTO(framesize), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top), Dt7(->pc), FRAME_CP, CFRAME_RESUME, Dt1(->glref), GG_G2DISP, Dt1(->cframe), Dt1(->status));
  1807. #line 644 "vm_x86.dasc"
  1808.   //|  set_vmstate INTERP
  1809.   //|  mov byte L:RB->status, RDL
  1810.   //|  mov BASE, L:RB->base
  1811.   //|  mov RD, L:RB->top
  1812.   //|  sub RD, RA
  1813.   //|  shr RD, 3
  1814.   //|  add RD, 1                                // RD = nresults+1
  1815.   //|  sub RA, BASE                        // RA = resultofs
  1816.   //|  mov PC, [BASE-4]
  1817.   //|  mov MULTRES, RD
  1818.   //|  test PC, FRAME_TYPE
  1819.   //|  jz ->BC_RET_Z
  1820.   //|  jmp ->vm_return
  1821.   //|
  1822.   //|->vm_pcall:                                // Setup protected C frame and enter VM.
  1823.   //|  // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
  1824.   //|  saveregs
  1825.   //|  mov PC, FRAME_CP
  1826.   //|.if X64
  1827.   //|  mov SAVE_ERRF, CARG4d
  1828.   //|.endif
  1829.   //|  jmp >1
  1830.   //|
  1831.   //|->vm_call:                                // Setup C frame and enter VM.
  1832.   //|  // (lua_State *L, TValue *base, int nres1)
  1833.   //|  saveregs
  1834.   //|  mov PC, FRAME_C
  1835.   //|
  1836.   //|1:  // Entry point for vm_pcall above (PC = ftype).
  1837.   //|.if X64
  1838.   //|  mov SAVE_NRES, CARG3d
  1839.   //|  mov L:RB, CARG1d                        // Caveat: CARG1d may be RA.
  1840.   //|  mov SAVE_L, CARG1d
  1841.   //|  mov RA, CARG2d
  1842.   //|.else
  1843.   //|  mov L:RB, SAVE_L
  1844.   //|  mov RA, INARG_BASE                        // Caveat: overlaps SAVE_CFRAME!
  1845.   //|.endif
  1846.   //|
  1847.   //|  mov DISPATCH, L:RB->glref                // Setup pointer to dispatch table.
  1848.   //|  mov KBASEa, L:RB->cframe                // Add our C frame to cframe chain.
  1849.   //|  mov SAVE_CFRAME, KBASEa
  1850.   dasm_put(Dst, 524, DISPATCH_GL(cur_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->status), Dt1(->base), Dt1(->top), FRAME_TYPE, FRAME_CP, FRAME_C, Dt1(->glref), Dt1(->cframe));
  1851. #line 686 "vm_x86.dasc"
  1852.   //|  mov SAVE_PC, L:RB                        // Any value outside of bytecode is ok.
  1853.   //|  add DISPATCH, GG_G2DISP
  1854.   //|.if X64
  1855.   //|  mov L:RB->cframe, rsp
  1856.   //|.else
  1857.   //|  mov L:RB->cframe, esp
  1858.   //|.endif
  1859.   //|
  1860.   //|2:  // Entry point for vm_resume/vm_cpcall (RA = base, RB = L, PC = ftype).
  1861.   //|  mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
  1862.   //|  set_vmstate INTERP
  1863.   //|  mov BASE, L:RB->base                // BASE = old base (used in vmeta_call).
  1864.   //|  add PC, RA
  1865.   //|  sub PC, BASE                        // PC = frame delta + frame type
  1866.   //|
  1867.   //|  mov RD, L:RB->top
  1868.   //|  sub RD, RA
  1869.   //|  shr NARGS:RD, 3
  1870.   //|  add NARGS:RD, 1                        // RD = nargs+1
  1871.   //|
  1872.   //|->vm_call_dispatch:
  1873.   //|  mov LFUNC:RB, [RA-8]
  1874.   //|  cmp dword [RA-4], LJ_TFUNC
  1875.   //|  jne ->vmeta_call                        // Ensure KBASE defined and != BASE.
  1876.   //|
  1877.   //|->vm_call_dispatch_f:
  1878.   //|  mov BASE, RA
  1879.   //|  ins_call
  1880.   //|  // BASE = new base, RB = func, RD = nargs+1, PC = caller PC
  1881.   //|
  1882.   //|->vm_cpcall:                                // Setup protected C frame, call C.
  1883.   //|  // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
  1884.   //|  saveregs
  1885.   //|.if X64
  1886.   //|  mov L:RB, CARG1d                        // Caveat: CARG1d may be RA.
  1887.   //|  mov SAVE_L, CARG1d
  1888.   //|.else
  1889.   //|  mov L:RB, SAVE_L
  1890.   //|  // Caveat: INARG_CP_* and SAVE_CFRAME/SAVE_NRES/SAVE_ERRF overlap!
  1891.   //|  mov RC, INARG_CP_UD                // Get args before they are overwritten.
  1892.   //|  mov RA, INARG_CP_FUNC
  1893.   //|  mov BASE, INARG_CP_CALL
  1894.   //|.endif
  1895.   //|  mov SAVE_PC, L:RB                        // Any value outside of bytecode is ok.
  1896.   //|
  1897.   //|  mov KBASE, L:RB->stack                // Compute -savestack(L, L->top).
  1898.   //|  sub KBASE, L:RB->top
  1899.   //|   mov DISPATCH, L:RB->glref                // Setup pointer to dispatch table.
  1900.   //|  mov SAVE_ERRF, 0                        // No error function.
  1901.   //|  mov SAVE_NRES, KBASE                // Neg. delta means cframe w/o frame.
  1902.   //|   add DISPATCH, GG_G2DISP
  1903.   //|  // Handler may change cframe_nres(L->cframe) or cframe_errfunc(L->cframe).
  1904.   //|
  1905.   //|.if X64
  1906.   //|  mov KBASEa, L:RB->cframe                // Add our C frame to cframe chain.
  1907.   //|  mov SAVE_CFRAME, KBASEa
  1908.   dasm_put(Dst, 635, GG_G2DISP, Dt1(->cframe), DISPATCH_GL(cur_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top), LJ_TFUNC, Dt7(->pc), Dt1(->stack), Dt1(->top), Dt1(->glref), GG_G2DISP, Dt1(->cframe));
  1909. #line 742 "vm_x86.dasc"
  1910.   //|  mov L:RB->cframe, rsp
  1911.   //|  mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
  1912.   //|
  1913.   //|  call CARG4                        // (lua_State *L, lua_CFunction func, void *ud)
  1914.   //|.else
  1915.   //|  mov ARG3, RC                        // Have to copy args downwards.
  1916.   //|  mov ARG2, RA
  1917.   //|  mov ARG1, L:RB
  1918.   //|
  1919.   //|  mov KBASE, L:RB->cframe                // Add our C frame to cframe chain.
  1920.   //|  mov SAVE_CFRAME, KBASE
  1921.   //|  mov L:RB->cframe, esp
  1922.   //|  mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
  1923.   //|
  1924.   //|  call BASE                        // (lua_State *L, lua_CFunction func, void *ud)
  1925.   //|.endif
  1926.   //|  // TValue * (new base) or NULL returned in eax (RC).
  1927.   //|  test RC, RC
  1928.   //|  jz ->vm_leave_cp                        // No base? Just remove C frame.
  1929.   //|  mov RA, RC
  1930.   //|  mov PC, FRAME_CP
  1931.   //|  jmp <2                                // Else continue with the call.
  1932.   //|
  1933.   //|//-----------------------------------------------------------------------
  1934.   //|//-- Metamethod handling ------------------------------------------------
  1935.   //|//-----------------------------------------------------------------------
  1936.   //|
  1937.   //|//-- Continuation dispatch ----------------------------------------------
  1938.   //|
  1939.   //|->cont_dispatch:
  1940.   //|  // BASE = meta base, RA = resultofs, RD = nresults+1 (also in MULTRES)
  1941.   //|  add RA, BASE
  1942.   //|  and PC, -8
  1943.   //|  mov RB, BASE
  1944.   //|  sub BASE, PC                        // Restore caller BASE.
  1945.   //|  mov dword [RA+RD*8-4], LJ_TNIL        // Ensure one valid arg.
  1946.   //|  mov RC, RA                                // ... in [RC]
  1947.   //|  mov PC, [RB-12]                        // Restore PC from [cont|PC].
  1948.   //|.if X64
  1949.   //|  movsxd RAa, dword [RB-16]                // May be negative on WIN64 with debug.
  1950.   //|.if FFI
  1951.   //|  cmp RA, 1
  1952.   //|  jbe >1
  1953.   //|.endif
  1954.   //|  lea KBASEa, qword [=>0]
  1955.   //|  add RAa, KBASEa
  1956.   //|.else
  1957.   //|  mov RA, dword [RB-16]
  1958.   //|.if FFI
  1959.   //|  cmp RA, 1
  1960.   //|  jbe >1
  1961.   //|.endif
  1962.   //|.endif
  1963.   //|  mov LFUNC:KBASE, [BASE-8]
  1964.   //|  mov KBASE, LFUNC:KBASE->pc
  1965.   //|  mov KBASE, [KBASE+PC2PROTO(k)]
  1966.   //|  // BASE = base, RC = result, RB = meta base
  1967.   //|  jmp RAa                                // Jump to continuation.
  1968.   //|
  1969.   //|.if FFI
  1970.   //|1:
  1971.   //|  je ->cont_ffi_callback                // cont = 1: return from FFI callback.
  1972.   //|  // cont = 0: Tail call from C function.
  1973.   //|  sub RB, BASE
  1974.   //|  shr RB, 3
  1975.   //|  lea RD, [RB-1]
  1976.   //|  jmp ->vm_call_tail
  1977.   //|.endif
  1978.   //|
  1979.   //|->cont_cat:                                // BASE = base, RC = result, RB = mbase
  1980.   //|  movzx RA, PC_RB
  1981.   dasm_put(Dst, 784, Dt1(->cframe), DISPATCH_GL(cur_L), FRAME_CP, LJ_TNIL, 0, Dt7(->pc), PC2PROTO(k));
  1982. #line 813 "vm_x86.dasc"
  1983.   //|  sub RB, 16
  1984.   //|  lea RA, [BASE+RA*8]
  1985.   //|  sub RA, RB
  1986.   //|  je ->cont_ra
  1987.   //|  neg RA
  1988.   //|  shr RA, 3
  1989.   //|.if X64WIN
  1990.   //|  mov CARG3d, RA
  1991.   //|  mov L:CARG1d, SAVE_L
  1992.   //|  mov L:CARG1d->base, BASE
  1993.   //|  mov RCa, [RC]
  1994.   //|  mov [RB], RCa
  1995.   //|  mov CARG2d, RB
  1996.   //|.elif X64
  1997.   //|  mov L:CARG1d, SAVE_L
  1998.   //|  mov L:CARG1d->base, BASE
  1999.   //|  mov CARG3d, RA
  2000.   //|  mov RAa, [RC]
  2001.   //|  mov [RB], RAa
  2002.   //|  mov CARG2d, RB
  2003.   //|.else
  2004.   //|  mov ARG3, RA
  2005.   //|  mov RA, [RC+4]
  2006.   //|  mov RC, [RC]
  2007.   //|  mov [RB+4], RA
  2008.   //|  mov [RB], RC
  2009.   //|  mov ARG2, RB
  2010.   //|.endif
  2011.   //|  jmp ->BC_CAT_Z
  2012.   //|
  2013.   //|//-- Table indexing metamethods -----------------------------------------
  2014.   //|
  2015.   //|->vmeta_tgets:
  2016.   //|  mov TMP1, RC                        // RC = GCstr *
  2017.   //|  mov TMP2, LJ_TSTR
  2018.   //|  lea RCa, TMP1                        // Store temp. TValue in TMP1/TMP2.
  2019.   //|  cmp PC_OP, BC_GGET
  2020.   //|  jne >1
  2021.   //|  lea RA, [DISPATCH+DISPATCH_GL(tmptv)]  // Store fn->l.env in g->tmptv.
  2022.   //|  mov [RA], TAB:RB                        // RB = GCtab *
  2023.   //|  mov dword [RA+4], LJ_TTAB
  2024.   //|  mov RB, RA
  2025.   //|  jmp >2
  2026.   //|
  2027.   //|->vmeta_tgetb:
  2028.   //|  movzx RC, PC_RC
  2029.   //|.if DUALNUM
  2030.   //|  mov TMP2, LJ_TISNUM
  2031.   //|  mov TMP1, RC
  2032.   //|.else
  2033.   //|  cvtsi2sd xmm0, RC
  2034.   //|  movsd TMPQ, xmm0
  2035.   //|.endif
  2036.   //|  lea RCa, TMPQ                        // Store temp. TValue in TMPQ.
  2037.   //|  jmp >1
  2038.   //|
  2039.   //|->vmeta_tgetv:
  2040.   //|  movzx RC, PC_RC                        // Reload TValue *k from RC.
  2041.   //|  lea RC, [BASE+RC*8]
  2042.   //|1:
  2043.   //|  movzx RB, PC_RB                        // Reload TValue *t from RB.
  2044.   dasm_put(Dst, 898, Dt1(->base), LJ_TSTR, BC_GGET, DISPATCH_GL(tmptv), LJ_TTAB, LJ_TISNUM);
  2045. #line 874 "vm_x86.dasc"
  2046.   //|  lea RB, [BASE+RB*8]
  2047.   //|2:
  2048.   //|.if X64
  2049.   //|  mov L:CARG1d, SAVE_L
  2050.   //|  mov L:CARG1d->base, BASE                // Caveat: CARG2d/CARG3d may be BASE.
  2051.   //|  mov CARG2d, RB
  2052.   //|  mov CARG3, RCa                        // May be 64 bit ptr to stack.
  2053.   //|  mov L:RB, L:CARG1d
  2054.   //|.else
  2055.   //|  mov ARG2, RB
  2056.   //|  mov L:RB, SAVE_L
  2057.   //|  mov ARG3, RC
  2058.   //|  mov ARG1, L:RB
  2059.   //|  mov L:RB->base, BASE
  2060.   //|.endif
  2061.   //|  mov SAVE_PC, PC
  2062.   //|  call extern lj_meta_tget                // (lua_State *L, TValue *o, TValue *k)
  2063.   //|  // TValue * (finished) or NULL (metamethod) returned in eax (RC).
  2064.   //|  mov BASE, L:RB->base
  2065.   //|  test RC, RC
  2066.   //|  jz >3
  2067.   //|->cont_ra:                                // BASE = base, RC = result
  2068.   //|  movzx RA, PC_RA
  2069.   //|.if X64
  2070.   //|  mov RBa, [RC]
  2071.   //|  mov [BASE+RA*8], RBa
  2072.   //|.else
  2073.   //|  mov RB, [RC+4]
  2074.   //|  mov RC, [RC]
  2075.   //|  mov [BASE+RA*8+4], RB
  2076.   //|  mov [BASE+RA*8], RC
  2077.   //|.endif
  2078.   //|  ins_next
  2079.   //|
  2080.   //|3:  // Call __index metamethod.
  2081.   //|  // BASE = base, L->top = new base, stack = cont/func/t/k
  2082.   //|  mov RA, L:RB->top
  2083.   //|  mov [RA-12], PC                        // [cont|PC]
  2084.   //|  lea PC, [RA+FRAME_CONT]
  2085.   //|  sub PC, BASE
  2086.   //|  mov LFUNC:RB, [RA-8]                // Guaranteed to be a function here.
  2087.   //|  mov NARGS:RD, 2+1                        // 2 args for func(t, k).
  2088.   //|  jmp ->vm_call_dispatch_f
  2089.   //|
  2090.   //|->vmeta_tgetr:
  2091.   //|  mov FCARG1, TAB:RB
  2092.   //|  mov RB, BASE                        // Save BASE.
  2093.   //|  mov FCARG2, RC                        // Caveat: FCARG2 == BASE
  2094.   //|  call extern lj_tab_getinth@8        // (GCtab *t, int32_t key)
  2095.   //|  // cTValue * or NULL returned in eax (RC).
  2096.   //|  movzx RA, PC_RA
  2097.   //|  mov BASE, RB                        // Restore BASE.
  2098.   //|  test RC, RC
  2099.   //|  jnz ->BC_TGETR_Z
  2100.   //|  mov dword [BASE+RA*8+4], LJ_TNIL
  2101.   //|  jmp ->BC_TGETR2_Z
  2102.   //|
  2103.   //|//-----------------------------------------------------------------------
  2104.   //|
  2105.   //|->vmeta_tsets:
  2106.   //|  mov TMP1, RC                        // RC = GCstr *
  2107.   //|  mov TMP2, LJ_TSTR
  2108.   //|  lea RCa, TMP1                        // Store temp. TValue in TMP1/TMP2.
  2109.   dasm_put(Dst, 1022, Dt1(->base), Dt1(->base), Dt1(->top), FRAME_CONT, 2+1, LJ_TNIL, LJ_TSTR);
  2110. #line 937 "vm_x86.dasc"
  2111.   //|  cmp PC_OP, BC_GSET
  2112.   //|  jne >1
  2113.   //|  lea RA, [DISPATCH+DISPATCH_GL(tmptv)]  // Store fn->l.env in g->tmptv.
  2114.   //|  mov [RA], TAB:RB                        // RB = GCtab *
  2115.   //|  mov dword [RA+4], LJ_TTAB
  2116.   //|  mov RB, RA
  2117.   //|  jmp >2
  2118.   //|
  2119.   //|->vmeta_tsetb:
  2120.   //|  movzx RC, PC_RC
  2121.   //|.if DUALNUM
  2122.   //|  mov TMP2, LJ_TISNUM
  2123.   //|  mov TMP1, RC
  2124.   //|.else
  2125.   //|  cvtsi2sd xmm0, RC
  2126.   //|  movsd TMPQ, xmm0
  2127.   //|.endif
  2128.   //|  lea RCa, TMPQ                        // Store temp. TValue in TMPQ.
  2129.   //|  jmp >1
  2130.   //|
  2131.   //|->vmeta_tsetv:
  2132.   //|  movzx RC, PC_RC                        // Reload TValue *k from RC.
  2133.   //|  lea RC, [BASE+RC*8]
  2134.   //|1:
  2135.   //|  movzx RB, PC_RB                        // Reload TValue *t from RB.
  2136.   //|  lea RB, [BASE+RB*8]
  2137.   //|2:
  2138.   //|.if X64
  2139.   //|  mov L:CARG1d, SAVE_L
  2140.   //|  mov L:CARG1d->base, BASE                // Caveat: CARG2d/CARG3d may be BASE.
  2141.   //|  mov CARG2d, RB
  2142.   //|  mov CARG3, RCa                        // May be 64 bit ptr to stack.
  2143.   //|  mov L:RB, L:CARG1d
  2144.   //|.else
  2145.   //|  mov ARG2, RB
  2146.   //|  mov L:RB, SAVE_L
  2147.   //|  mov ARG3, RC
  2148.   //|  mov ARG1, L:RB
  2149.   //|  mov L:RB->base, BASE
  2150.   //|.endif
  2151.   //|  mov SAVE_PC, PC
  2152.   //|  call extern lj_meta_tset                // (lua_State *L, TValue *o, TValue *k)
  2153.   //|  // TValue * (finished) or NULL (metamethod) returned in eax (RC).
  2154.   //|  mov BASE, L:RB->base
  2155.   //|  test RC, RC
  2156.   //|  jz >3
  2157.   //|  // NOBARRIER: lj_meta_tset ensures the table is not black.
  2158.   //|  movzx RA, PC_RA
  2159.   //|.if X64
  2160.   //|  mov RBa, [BASE+RA*8]
  2161.   //|  mov [RC], RBa
  2162.   //|.else
  2163.   //|  mov RB, [BASE+RA*8+4]
  2164.   //|  mov RA, [BASE+RA*8]
  2165.   //|  mov [RC+4], RB
  2166.   //|  mov [RC], RA
  2167.   //|.endif
  2168.   //|->cont_nop:                                // BASE = base, (RC = result)
  2169.   //|  ins_next
  2170.   //|
  2171.   //|3:  // Call __newindex metamethod.
  2172.   //|  // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
  2173.   //|  mov RA, L:RB->top
  2174.   dasm_put(Dst, 1171, BC_GSET, DISPATCH_GL(tmptv), LJ_TTAB, LJ_TISNUM, Dt1(->base), Dt1(->base));
  2175. #line 1000 "vm_x86.dasc"
  2176.   //|  mov [RA-12], PC                        // [cont|PC]
  2177.   //|  movzx RC, PC_RA
  2178.   //|  // Copy value to third argument.
  2179.   //|.if X64
  2180.   //|  mov RBa, [BASE+RC*8]
  2181.   //|  mov [RA+16], RBa
  2182.   //|.else
  2183.   //|  mov RB, [BASE+RC*8+4]
  2184.   //|  mov RC, [BASE+RC*8]
  2185.   //|  mov [RA+20], RB
  2186.   //|  mov [RA+16], RC
  2187.   //|.endif
  2188.   //|  lea PC, [RA+FRAME_CONT]
  2189.   //|  sub PC, BASE
  2190.   //|  mov LFUNC:RB, [RA-8]                // Guaranteed to be a function here.
  2191.   //|  mov NARGS:RD, 3+1                        // 3 args for func(t, k, v).
  2192.   //|  jmp ->vm_call_dispatch_f
  2193.   //|
  2194.   //|->vmeta_tsetr:
  2195.   //|.if X64WIN
  2196.   //|  mov L:CARG1d, SAVE_L
  2197.   //|  mov CARG3d, RC
  2198.   //|  mov L:CARG1d->base, BASE
  2199.   //|  xchg CARG2d, TAB:RB                // Caveat: CARG2d == BASE.
  2200.   //|.elif X64
  2201.   //|  mov L:CARG1d, SAVE_L
  2202.   //|  mov CARG2d, TAB:RB
  2203.   //|  mov L:CARG1d->base, BASE
  2204.   //|  mov RB, BASE                        // Save BASE.
  2205.   //|  mov CARG3d, RC                        // Caveat: CARG3d == BASE.
  2206.   //|.else
  2207.   //|  mov L:RA, SAVE_L
  2208.   //|  mov ARG2, TAB:RB
  2209.   //|  mov RB, BASE                        // Save BASE.
  2210.   //|  mov ARG3, RC
  2211.   //|  mov ARG1, L:RA
  2212.   //|  mov L:RA->base, BASE
  2213.   //|.endif
  2214.   //|  mov SAVE_PC, PC
  2215.   //|  call extern lj_tab_setinth  // (lua_State *L, GCtab *t, int32_t key)
  2216.   //|  // TValue * returned in eax (RC).
  2217.   //|  movzx RA, PC_RA
  2218.   //|  mov BASE, RB                        // Restore BASE.
  2219.   //|  jmp ->BC_TSETR_Z
  2220.   //|
  2221.   //|//-- Comparison metamethods ---------------------------------------------
  2222.   //|
  2223.   //|->vmeta_comp:
  2224.   //|.if X64
  2225.   //|  mov L:RB, SAVE_L
  2226.   //|  mov L:RB->base, BASE                // Caveat: CARG2d/CARG3d == BASE.
  2227.   //|.if X64WIN
  2228.   //|  lea CARG3d, [BASE+RD*8]
  2229.   //|  lea CARG2d, [BASE+RA*8]
  2230.   //|.else
  2231.   //|  lea CARG2d, [BASE+RA*8]
  2232.   //|  lea CARG3d, [BASE+RD*8]
  2233.   //|.endif
  2234.   //|  mov CARG1d, L:RB                        // Caveat: CARG1d/CARG4d == RA.
  2235.   //|  movzx CARG4d, PC_OP
  2236.   //|.else
  2237.   //|  movzx RB, PC_OP
  2238.   //|  lea RD, [BASE+RD*8]
  2239.   //|  lea RA, [BASE+RA*8]
  2240.   //|  mov ARG4, RB
  2241.   //|  mov L:RB, SAVE_L
  2242.   //|  mov ARG3, RD
  2243.   //|  mov ARG2, RA
  2244.   //|  mov ARG1, L:RB
  2245.   //|  mov L:RB->base, BASE
  2246.   //|.endif
  2247.   //|  mov SAVE_PC, PC
  2248.   //|  call extern lj_meta_comp        // (lua_State *L, TValue *o1, *o2, int op)
  2249.   //|  // 0/1 or TValue * (metamethod) returned in eax (RC).
  2250.   //|3:
  2251.   //|  mov BASE, L:RB->base
  2252.   //|  cmp RC, 1
  2253.   //|  ja ->vmeta_binop
  2254.   //|4:
  2255.   //|  lea PC, [PC+4]
  2256.   //|  jb >6
  2257.   //|5:
  2258.   //|  movzx RD, PC_RD
  2259.   //|  branchPC RD
  2260.   //|6:
  2261.   //|  ins_next
  2262.   dasm_put(Dst, 1316, Dt1(->top), FRAME_CONT, 3+1, Dt1(->base), Dt1(->base), Dt1(->base), -BCBIAS_J*4);
  2263. #line 1086 "vm_x86.dasc"
  2264.   //|
  2265.   //|->cont_condt:                        // BASE = base, RC = result
  2266.   //|  add PC, 4
  2267.   //|  cmp dword [RC+4], LJ_TISTRUECOND        // Branch if result is true.
  2268.   //|  jb <5
  2269.   //|  jmp <6
  2270.   //|
  2271.   //|->cont_condf:                        // BASE = base, RC = result
  2272.   //|  cmp dword [RC+4], LJ_TISTRUECOND        // Branch if result is false.
  2273.   //|  jmp <4
  2274.   //|
  2275.   //|->vmeta_equal:
  2276.   //|  sub PC, 4
  2277.   //|.if X64WIN
  2278.   //|  mov CARG3d, RD
  2279.   //|  mov CARG4d, RB
  2280.   //|  mov L:RB, SAVE_L
  2281.   //|  mov L:RB->base, BASE                // Caveat: CARG2d == BASE.
  2282.   //|  mov CARG2d, RA
  2283.   //|  mov CARG1d, L:RB                        // Caveat: CARG1d == RA.
  2284.   //|.elif X64
  2285.   //|  mov CARG2d, RA
  2286.   //|  mov CARG4d, RB                        // Caveat: CARG4d == RA.
  2287.   //|  mov L:RB, SAVE_L
  2288.   //|  mov L:RB->base, BASE                // Caveat: CARG3d == BASE.
  2289.   //|  mov CARG3d, RD
  2290.   //|  mov CARG1d, L:RB
  2291.   //|.else
  2292.   //|  mov ARG4, RB
  2293.   //|  mov L:RB, SAVE_L
  2294.   //|  mov ARG3, RD
  2295.   //|  mov ARG2, RA
  2296.   //|  mov ARG1, L:RB
  2297.   //|  mov L:RB->base, BASE
  2298.   //|.endif
  2299.   //|  mov SAVE_PC, PC
  2300.   //|  call extern lj_meta_equal        // (lua_State *L, GCobj *o1, *o2, int ne)
  2301.   //|  // 0/1 or TValue * (metamethod) returned in eax (RC).
  2302.   //|  jmp <3
  2303.   //|
  2304.   //|->vmeta_equal_cd:
  2305.   //|.if FFI
  2306.   //|  sub PC, 4
  2307.   //|  mov L:RB, SAVE_L
  2308.   //|  mov L:RB->base, BASE
  2309.   //|  mov FCARG1, L:RB
  2310.   //|  mov FCARG2, dword [PC-4]
  2311.   //|  mov SAVE_PC, PC
  2312.   //|  call extern lj_meta_equal_cd@8        // (lua_State *L, BCIns ins)
  2313.   //|  // 0/1 or TValue * (metamethod) returned in eax (RC).
  2314.   //|  jmp <3
  2315.   //|.endif
  2316.   //|
  2317.   //|->vmeta_istype:
  2318.   //|.if X64
  2319.   //|  mov L:RB, SAVE_L
  2320.   //|  mov L:RB->base, BASE                // Caveat: CARG2d/CARG3d may be BASE.
  2321.   //|  mov CARG2d, RA
  2322.   dasm_put(Dst, 1455, LJ_TISTRUECOND, LJ_TISTRUECOND, Dt1(->base), Dt1(->base), Dt1(->base));
  2323. #line 1144 "vm_x86.dasc"
  2324.   //|  movzx CARG3d, PC_RD
  2325.   //|  mov L:CARG1d, L:RB
  2326.   //|.else
  2327.   //|  movzx RD, PC_RD
  2328.   //|  mov ARG2, RA
  2329.   //|  mov L:RB, SAVE_L
  2330.   //|  mov ARG3, RD
  2331.   //|  mov ARG1, L:RB
  2332.   //|  mov L:RB->base, BASE
  2333.   //|.endif
  2334.   //|  mov SAVE_PC, PC
  2335.   //|  call extern lj_meta_istype  // (lua_State *L, BCReg ra, BCReg tp)
  2336.   //|  mov BASE, L:RB->base
  2337.   //|  jmp <6
  2338.   //|
  2339.   //|//-- Arithmetic metamethods ---------------------------------------------
  2340.   //|
  2341.   //|->vmeta_arith_vno:
  2342.   //|.if DUALNUM
  2343.   //|  movzx RB, PC_RB
  2344.   //|.endif
  2345.   //|->vmeta_arith_vn:
  2346.   //|  lea RC, [KBASE+RC*8]
  2347.   //|  jmp >1
  2348.   //|
  2349.   //|->vmeta_arith_nvo:
  2350.   //|.if DUALNUM
  2351.   //|  movzx RC, PC_RC
  2352.   //|.endif
  2353.   //|->vmeta_arith_nv:
  2354.   //|  lea RC, [KBASE+RC*8]
  2355.   //|  lea RB, [BASE+RB*8]
  2356.   //|  xchg RB, RC
  2357.   //|  jmp >2
  2358.   //|
  2359.   //|->vmeta_unm:
  2360.   //|  lea RC, [BASE+RD*8]
  2361.   //|  mov RB, RC
  2362.   //|  jmp >2
  2363.   //|
  2364.   //|->vmeta_arith_vvo:
  2365.   //|.if DUALNUM
  2366.   //|  movzx RB, PC_RB
  2367.   //|.endif
  2368.   //|->vmeta_arith_vv:
  2369.   //|  lea RC, [BASE+RC*8]
  2370.   //|1:
  2371.   //|  lea RB, [BASE+RB*8]
  2372.   //|2:
  2373.   //|  lea RA, [BASE+RA*8]
  2374.   //|.if X64WIN
  2375.   //|  mov CARG3d, RB
  2376.   //|  mov CARG4d, RC
  2377.   //|  movzx RC, PC_OP
  2378.   //|  mov ARG5d, RC
  2379.   //|  mov L:RB, SAVE_L
  2380.   //|  mov L:RB->base, BASE                // Caveat: CARG2d == BASE.
  2381.   //|  mov CARG2d, RA
  2382.   //|  mov CARG1d, L:RB                        // Caveat: CARG1d == RA.
  2383.   //|.elif X64
  2384.   //|  movzx CARG5d, PC_OP
  2385.   //|  mov CARG2d, RA
  2386.   //|  mov CARG4d, RC                        // Caveat: CARG4d == RA.
  2387.   //|  mov L:CARG1d, SAVE_L
  2388.   //|  mov L:CARG1d->base, BASE                // Caveat: CARG3d == BASE.
  2389.   //|  mov CARG3d, RB
  2390.   //|  mov L:RB, L:CARG1d
  2391.   //|.else
  2392.   //|  mov ARG3, RB
  2393.   //|  mov L:RB, SAVE_L
  2394.   //|  mov ARG4, RC
  2395.   //|  movzx RC, PC_OP
  2396.   //|  mov ARG2, RA
  2397.   //|  mov ARG5, RC
  2398.   //|  mov ARG1, L:RB
  2399.   //|  mov L:RB->base, BASE
  2400.   //|.endif
  2401.   //|  mov SAVE_PC, PC
  2402.   //|  call extern lj_meta_arith        // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
  2403.   //|  // NULL (finished) or TValue * (metamethod) returned in eax (RC).
  2404.   //|  mov BASE, L:RB->base
  2405.   //|  test RC, RC
  2406.   dasm_put(Dst, 1581, Dt1(->base), Dt1(->base), Dt1(->base));
  2407. #line 1226 "vm_x86.dasc"
  2408.   //|  jz ->cont_nop
  2409.   //|
  2410.   //|  // Call metamethod for binary op.
  2411.   //|->vmeta_binop:
  2412.   //|  // BASE = base, RC = new base, stack = cont/func/o1/o2
  2413.   //|  mov RA, RC
  2414.   //|  sub RC, BASE
  2415.   //|  mov [RA-12], PC                        // [cont|PC]
  2416.   //|  lea PC, [RC+FRAME_CONT]
  2417.   //|  mov NARGS:RD, 2+1                        // 2 args for func(o1, o2).
  2418.   //|  jmp ->vm_call_dispatch
  2419.   //|
  2420.   //|->vmeta_len:
  2421.   //|  mov L:RB, SAVE_L
  2422.   //|  mov L:RB->base, BASE
  2423.   //|  lea FCARG2, [BASE+RD*8]                // Caveat: FCARG2 == BASE
  2424.   //|  mov L:FCARG1, L:RB
  2425.   //|  mov SAVE_PC, PC
  2426.   //|  call extern lj_meta_len@8                // (lua_State *L, TValue *o)
  2427.   //|  // NULL (retry) or TValue * (metamethod) returned in eax (RC).
  2428.   //|  mov BASE, L:RB->base
  2429.   dasm_put(Dst, 1714, FRAME_CONT, 2+1, Dt1(->base), Dt1(->base));
  2430. #line 1247 "vm_x86.dasc"
  2431. #if LJ_52
  2432.   //|  test RC, RC
  2433.   //|  jne ->vmeta_binop                        // Binop call for compatibility.
  2434.   //|  movzx RD, PC_RD
  2435.   //|  mov TAB:FCARG1, [BASE+RD*8]
  2436.   //|  jmp ->BC_LEN_Z
  2437.   dasm_put(Dst, 1766);
  2438. #line 1253 "vm_x86.dasc"
  2439. #else
  2440.   //|  jmp ->vmeta_binop                        // Binop call for compatibility.
  2441.   dasm_put(Dst, 1785);
  2442. #line 1255 "vm_x86.dasc"
  2443. #endif
  2444.   //|
  2445.   //|//-- Call metamethod ----------------------------------------------------
  2446.   //|
  2447.   //|->vmeta_call_ra:
  2448.   //|  lea RA, [BASE+RA*8+8]
  2449.   //|->vmeta_call:                        // Resolve and call __call metamethod.
  2450.   //|  // BASE = old base, RA = new base, RC = nargs+1, PC = return
  2451.   //|  mov TMP2, RA                        // Save RA, RC for us.
  2452.   //|  mov TMP1, NARGS:RD
  2453.   //|  sub RA, 8
  2454.   //|.if X64
  2455.   //|  mov L:RB, SAVE_L
  2456.   //|  mov L:RB->base, BASE                // Caveat: CARG2d/CARG3d may be BASE.
  2457.   //|  mov CARG2d, RA
  2458.   //|  lea CARG3d, [RA+NARGS:RD*8]
  2459.   //|  mov CARG1d, L:RB                        // Caveat: CARG1d may be RA.
  2460.   //|.else
  2461.   //|  lea RC, [RA+NARGS:RD*8]
  2462.   //|  mov L:RB, SAVE_L
  2463.   //|  mov ARG2, RA
  2464.   //|  mov ARG3, RC
  2465.   //|  mov ARG1, L:RB
  2466.   //|  mov L:RB->base, BASE                // This is the callers base!
  2467.   //|.endif
  2468.   //|  mov SAVE_PC, PC
  2469.   //|  call extern lj_meta_call        // (lua_State *L, TValue *func, TValue *top)
  2470.   //|  mov BASE, L:RB->base
  2471.   //|  mov RA, TMP2
  2472.   //|  mov NARGS:RD, TMP1
  2473.   //|  mov LFUNC:RB, [RA-8]
  2474.   //|  add NARGS:RD, 1
  2475.   //|  // This is fragile. L->base must not move, KBASE must always be defined.
  2476.   //|  cmp KBASE, BASE                        // Continue with CALLT if flag set.
  2477.   //|  je ->BC_CALLT_Z
  2478.   //|  mov BASE, RA
  2479.   //|  ins_call                                // Otherwise call resolved metamethod.
  2480.   //|
  2481.   //|//-- Argument coercion for 'for' statement ------------------------------
  2482.   //|
  2483.   //|->vmeta_for:
  2484.   //|  mov L:RB, SAVE_L
  2485.   //|  mov L:RB->base, BASE
  2486.   //|  mov FCARG2, RA                        // Caveat: FCARG2 == BASE
  2487.   //|  mov L:FCARG1, L:RB                        // Caveat: FCARG1 == RA
  2488.   //|  mov SAVE_PC, PC
  2489.   //|  call extern lj_meta_for@8        // (lua_State *L, TValue *base)
  2490.   //|  mov BASE, L:RB->base
  2491.   //|  mov RC, [PC-4]
  2492.   //|  movzx RA, RCH
  2493.   //|  movzx OP, RCL
  2494.   //|  shr RC, 16
  2495.   //|.if X64
  2496.   //|  jmp aword [DISPATCH+OP*8+GG_DISP2STATIC]        // Retry FORI or JFORI.
  2497.   //|.else
  2498.   //|  jmp aword [DISPATCH+OP*4+GG_DISP2STATIC]        // Retry FORI or JFORI.
  2499.   //|.endif
  2500.   //|
  2501.   //|//-----------------------------------------------------------------------
  2502.   //|//-- Fast functions -----------------------------------------------------
  2503.   //|//-----------------------------------------------------------------------
  2504.   //|
  2505.   //|.macro .ffunc, name
  2506.   //|->ff_ .. name:
  2507.   //|.endmacro
  2508.   //|
  2509.   //|.macro .ffunc_1, name
  2510.   //|->ff_ .. name:
  2511.   //|  cmp NARGS:RD, 1+1;  jb ->fff_fallback
  2512.   //|.endmacro
  2513.   //|
  2514.   //|.macro .ffunc_2, name
  2515.   //|->ff_ .. name:
  2516.   //|  cmp NARGS:RD, 2+1;  jb ->fff_fallback
  2517.   //|.endmacro
  2518.   //|
  2519.   //|.macro .ffunc_nsse, name, op
  2520.   //|  .ffunc_1 name
  2521.   //|  cmp dword [BASE+4], LJ_TISNUM;  jae ->fff_fallback
  2522.   //|  op xmm0, qword [BASE]
  2523.   //|.endmacro
  2524.   //|
  2525.   //|.macro .ffunc_nsse, name
  2526.   //|  .ffunc_nsse name, movsd
  2527.   //|.endmacro
  2528.   //|
  2529.   //|.macro .ffunc_nnsse, name
  2530.   //|  .ffunc_2 name
  2531.   //|  cmp dword [BASE+4], LJ_TISNUM;  jae ->fff_fallback
  2532.   //|  cmp dword [BASE+12], LJ_TISNUM;  jae ->fff_fallback
  2533.   //|  movsd xmm0, qword [BASE]
  2534.   //|  movsd xmm1, qword [BASE+8]
  2535.   //|.endmacro
  2536.   //|
  2537.   //|.macro .ffunc_nnr, name
  2538.   //|  .ffunc_2 name
  2539.   //|  cmp dword [BASE+4], LJ_TISNUM;  jae ->fff_fallback
  2540.   //|  cmp dword [BASE+12], LJ_TISNUM;  jae ->fff_fallback
  2541.   //|  fld qword [BASE+8]
  2542.   //|  fld qword [BASE]
  2543.   //|.endmacro
  2544.   //|
  2545.   //|// Inlined GC threshold check. Caveat: uses label 1.
  2546.   //|.macro ffgccheck
  2547.   //|  mov RB, [DISPATCH+DISPATCH_GL(gc.total)]
  2548.   //|  cmp RB, [DISPATCH+DISPATCH_GL(gc.threshold)]
  2549.   //|  jb >1
  2550.   //|  call ->fff_gcstep
  2551.   //|1:
  2552.   //|.endmacro
  2553.   //|
  2554.   //|//-- Base library: checks -----------------------------------------------
  2555.   //|
  2556.   //|.ffunc_1 assert
  2557.   //|  mov RB, [BASE+4]
  2558.   //|  cmp RB, LJ_TISTRUECOND;  jae ->fff_fallback
  2559.   //|  mov PC, [BASE-4]
  2560.   //|  mov MULTRES, RD
  2561.   //|  mov [BASE-4], RB
  2562.   //|  mov RB, [BASE]
  2563.   //|  mov [BASE-8], RB
  2564.   //|  sub RD, 2
  2565.   //|  jz >2
  2566.   //|  mov RA, BASE
  2567.   dasm_put(Dst, 1790, Dt1(->base), Dt1(->base), Dt7(->pc), Dt1(->base), Dt1(->base), GG_DISP2STATIC, 1+1, LJ_TISTRUECOND);
  2568. #line 1379 "vm_x86.dasc"
  2569.   //|1:
  2570.   //|  add RA, 8
  2571.   //|.if X64
  2572.   //|  mov RBa, [RA]
  2573.   //|  mov [RA-8], RBa
  2574.   //|.else
  2575.   //|  mov RB, [RA+4]
  2576.   //|  mov [RA-4], RB
  2577.   //|  mov RB, [RA]
  2578.   //|  mov [RA-8], RB
  2579.   //|.endif
  2580.   //|  sub RD, 1
  2581.   //|  jnz <1
  2582.   //|2:
  2583.   //|  mov RD, MULTRES
  2584.   //|  jmp ->fff_res_
  2585.   //|
  2586.   //|.ffunc_1 type
  2587.   //|  mov RB, [BASE+4]
  2588.   //|.if X64
  2589.   //|  mov RA, RB
  2590.   //|  sar RA, 15
  2591.   //|  cmp RA, -2
  2592.   //|  je >3
  2593.   //|.endif
  2594.   //|  mov RC, ~LJ_TNUMX
  2595.   //|  not RB
  2596.   //|  cmp RC, RB
  2597.   //|  cmova RC, RB
  2598.   //|2:
  2599.   //|  mov CFUNC:RB, [BASE-8]
  2600.   //|  mov STR:RC, [CFUNC:RB+RC*8+((char *)(&((GCfuncC *)0)->upvalue))]
  2601.   //|  mov PC, [BASE-4]
  2602.   //|  mov dword [BASE-4], LJ_TSTR
  2603.   //|  mov [BASE-8], STR:RC
  2604.   //|  jmp ->fff_res1
  2605.   //|.if X64
  2606.   //|3:
  2607.   //|  mov RC, ~LJ_TLIGHTUD
  2608.   //|  jmp <2
  2609.   dasm_put(Dst, 1976, 1+1, ~LJ_TNUMX, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, ~LJ_TLIGHTUD);
  2610. #line 1419 "vm_x86.dasc"
  2611.   //|.endif
  2612.   //|
  2613.   //|//-- Base library: getters and setters ---------------------------------
  2614.   //|
  2615.   //|.ffunc_1 getmetatable
  2616.   //|  mov RB, [BASE+4]
  2617.   //|  mov PC, [BASE-4]
  2618.   //|  cmp RB, LJ_TTAB;  jne >6
  2619.   //|1:  // Field metatable must be at same offset for GCtab and GCudata!
  2620.   //|  mov TAB:RB, [BASE]
  2621.   //|  mov TAB:RB, TAB:RB->metatable
  2622.   //|2:
  2623.   //|  test TAB:RB, TAB:RB
  2624.   //|  mov dword [BASE-4], LJ_TNIL
  2625.   //|  jz ->fff_res1
  2626.   //|  mov STR:RC, [DISPATCH+DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable)]
  2627.   //|  mov dword [BASE-4], LJ_TTAB        // Store metatable as default result.
  2628.   //|  mov [BASE-8], TAB:RB
  2629.   //|  mov RA, TAB:RB->hmask
  2630.   //|  and RA, STR:RC->hash
  2631.   //|  imul RA, #NODE
  2632.   //|  add NODE:RA, TAB:RB->node
  2633.   dasm_put(Dst, 2080, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL, DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable), LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node));
  2634. #line 1441 "vm_x86.dasc"
  2635.   //|3:  // Rearranged logic, because we expect _not_ to find the key.
  2636.   //|  cmp dword NODE:RA->key.it, LJ_TSTR
  2637.   //|  jne >4
  2638.   //|  cmp dword NODE:RA->key.gcr, STR:RC
  2639.   //|  je >5
  2640.   //|4:
  2641.   //|  mov NODE:RA, NODE:RA->next
  2642.   //|  test NODE:RA, NODE:RA
  2643.   //|  jnz <3
  2644.   //|  jmp ->fff_res1                        // Not found, keep default result.
  2645.   //|5:
  2646.   //|  mov RB, [RA+4]
  2647.   //|  cmp RB, LJ_TNIL;  je ->fff_res1        // Ditto for nil value.
  2648.   //|  mov RC, [RA]
  2649.   //|  mov [BASE-4], RB                        // Return value of mt.__metatable.
  2650.   //|  mov [BASE-8], RC
  2651.   //|  jmp ->fff_res1
  2652.   //|
  2653.   //|6:
  2654.   //|  cmp RB, LJ_TUDATA;  je <1
  2655.   dasm_put(Dst, 2153, Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next), LJ_TNIL);
  2656. #line 1461 "vm_x86.dasc"
  2657.   //|.if X64
  2658.   //|  cmp RB, LJ_TNUMX;  ja >8
  2659.   //|  cmp RB, LJ_TISNUM;  jbe >7
  2660.   //|  mov RB, LJ_TLIGHTUD
  2661.   //|  jmp >8
  2662.   //|7:
  2663.   //|.else
  2664.   //|  cmp RB, LJ_TISNUM;  ja >8
  2665.   //|.endif
  2666.   //|  mov RB, LJ_TNUMX
  2667.   //|8:
  2668.   //|  not RB
  2669.   //|  mov TAB:RB, [DISPATCH+RB*4+DISPATCH_GL(gcroot[GCROOT_BASEMT])]
  2670.   //|  jmp <2
  2671.   //|
  2672.   //|.ffunc_2 setmetatable
  2673.   dasm_put(Dst, 2218, LJ_TUDATA, LJ_TNUMX, LJ_TISNUM, LJ_TLIGHTUD, LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT]), 2+1);
  2674. #line 1477 "vm_x86.dasc"
  2675.   //|  cmp dword [BASE+4], LJ_TTAB;  jne ->fff_fallback
  2676.   //|  // Fast path: no mt for table yet and not clearing the mt.
  2677.   //|  mov TAB:RB, [BASE]
  2678.   //|  cmp dword TAB:RB->metatable, 0;  jne ->fff_fallback
  2679.   //|  cmp dword [BASE+12], LJ_TTAB;  jne ->fff_fallback
  2680.   //|  mov TAB:RC, [BASE+8]
  2681.   //|  mov TAB:RB->metatable, TAB:RC
  2682.   //|  mov PC, [BASE-4]
  2683.   //|  mov dword [BASE-4], LJ_TTAB                // Return original table.
  2684.   //|  mov [BASE-8], TAB:RB
  2685.   //|  test byte TAB:RB->marked, LJ_GC_BLACK        // isblack(table)
  2686.   //|  jz >1
  2687.   //|  // Possible write barrier. Table is black, but skip iswhite(mt) check.
  2688.   //|  barrierback TAB:RB, RC
  2689.   dasm_put(Dst, 2274, LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->marked), LJ_GC_BLACK, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain));
  2690. #line 1491 "vm_x86.dasc"
  2691.   //|1:
  2692.   //|  jmp ->fff_res1
  2693.   //|
  2694.   //|.ffunc_2 rawget
  2695.   //|  cmp dword [BASE+4], LJ_TTAB;  jne ->fff_fallback
  2696.   //|.if X64WIN
  2697.   //|  mov RB, BASE                        // Save BASE.
  2698.   //|  lea CARG3d, [BASE+8]
  2699.   //|  mov CARG2d, [BASE]                        // Caveat: CARG2d == BASE.
  2700.   //|  mov CARG1d, SAVE_L
  2701.   //|.elif X64
  2702.   //|  mov RB, BASE                        // Save BASE.
  2703.   //|  mov CARG2d, [BASE]
  2704.   //|  lea CARG3d, [BASE+8]                // Caveat: CARG3d == BASE.
  2705.   //|  mov CARG1d, SAVE_L
  2706.   //|.else
  2707.   //|  mov TAB:RD, [BASE]
  2708.   //|  mov L:RB, SAVE_L
  2709.   //|  mov ARG2, TAB:RD
  2710.   //|  mov ARG1, L:RB
  2711.   //|  mov RB, BASE                        // Save BASE.
  2712.   //|  add BASE, 8
  2713.   //|  mov ARG3, BASE
  2714.   //|.endif
  2715.   //|  call extern lj_tab_get        // (lua_State *L, GCtab *t, cTValue *key)
  2716.   //|  // cTValue * returned in eax (RD).
  2717.   //|  mov BASE, RB                        // Restore BASE.
  2718.   //|  // Copy table slot.
  2719.   //|.if X64
  2720.   //|  mov RBa, [RD]
  2721.   //|  mov PC, [BASE-4]
  2722.   //|  mov [BASE-8], RBa
  2723.   //|.else
  2724.   //|  mov RB, [RD]
  2725.   //|  mov RD, [RD+4]
  2726.   //|  mov PC, [BASE-4]
  2727.   //|  mov [BASE-8], RB
  2728.   //|  mov [BASE-4], RD
  2729.   //|.endif
  2730.   //|  jmp ->fff_res1
  2731.   //|
  2732.   //|//-- Base library: conversions ------------------------------------------
  2733.   //|
  2734.   //|.ffunc tonumber
  2735.   //|  // Only handles the number case inline (without a base argument).
  2736.   //|  cmp NARGS:RD, 1+1;  jne ->fff_fallback        // Exactly one argument.
  2737.   //|  cmp dword [BASE+4], LJ_TISNUM
  2738.   //|.if DUALNUM
  2739.   //|  jne >1
  2740.   //|  mov RB, dword [BASE]; jmp ->fff_resi
  2741.   dasm_put(Dst, 2343, DISPATCH_GL(gc.grayagain), Dt6(->gclist), 2+1, LJ_TTAB, 1+1, LJ_TISNUM);
  2742. #line 1541 "vm_x86.dasc"
  2743.   //|1:
  2744.   //|  ja ->fff_fallback
  2745.   //|.else
  2746.   //|  jae ->fff_fallback
  2747.   //|.endif
  2748.   //|  movsd xmm0, qword [BASE]; jmp ->fff_resxmm0
  2749.   //|
  2750.   //|.ffunc_1 tostring
  2751.   //|  // Only handles the string or number case inline.
  2752.   //|  mov PC, [BASE-4]
  2753.   //|  cmp dword [BASE+4], LJ_TSTR;  jne >3
  2754.   //|  // A __tostring method in the string base metatable is ignored.
  2755.   //|  mov STR:RD, [BASE]
  2756.   //|2:
  2757.   //|  mov dword [BASE-4], LJ_TSTR
  2758.   //|  mov [BASE-8], STR:RD
  2759.   //|  jmp ->fff_res1
  2760.   //|3:  // Handle numbers inline, unless a number base metatable is present.
  2761.   //|  cmp dword [BASE+4], LJ_TISNUM;  ja ->fff_fallback
  2762.   dasm_put(Dst, 2429, 1+1, LJ_TSTR, LJ_TSTR, LJ_TISNUM);
  2763. #line 1560 "vm_x86.dasc"
  2764.   //|  cmp dword [DISPATCH+DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])], 0
  2765.   //|  jne ->fff_fallback
  2766.   //|  ffgccheck                                // Caveat: uses label 1.
  2767.   //|  mov L:RB, SAVE_L
  2768.   //|  mov L:RB->base, BASE                // Add frame since C call can throw.
  2769.   //|  mov SAVE_PC, PC                        // Redundant (but a defined value).
  2770.   //|.if X64 and not X64WIN
  2771.   //|  mov FCARG2, BASE                        // Otherwise: FCARG2 == BASE
  2772.   //|.endif
  2773.   //|  mov L:FCARG1, L:RB
  2774.   //|.if DUALNUM
  2775.   //|  call extern lj_strfmt_number@8        // (lua_State *L, cTValue *o)
  2776.   //|.else
  2777.   //|  call extern lj_strfmt_num@8        // (lua_State *L, lua_Number *np)
  2778.   //|.endif
  2779.   //|  // GCstr returned in eax (RD).
  2780.   //|  mov BASE, L:RB->base
  2781.   //|  jmp <2
  2782.   //|
  2783.   //|//-- Base library: iterators -------------------------------------------
  2784.   //|
  2785.   //|.ffunc_1 next
  2786.   //|  je >2                                // Missing 2nd arg?
  2787.   dasm_put(Dst, 2498, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), Dt1(->base), 1+1);
  2788. #line 1583 "vm_x86.dasc"
  2789.   //|1:
  2790.   //|  cmp dword [BASE+4], LJ_TTAB;  jne ->fff_fallback
  2791.   //|  mov L:RB, SAVE_L
  2792.   //|  mov L:RB->base, BASE                // Add frame since C call can throw.
  2793.   //|  mov L:RB->top, BASE                // Dummy frame length is ok.
  2794.   //|  mov PC, [BASE-4]
  2795.   //|.if X64WIN
  2796.   //|  lea CARG3d, [BASE+8]
  2797.   //|  mov CARG2d, [BASE]                        // Caveat: CARG2d == BASE.
  2798.   //|  mov CARG1d, L:RB
  2799.   //|.elif X64
  2800.   //|  mov CARG2d, [BASE]
  2801.   //|  lea CARG3d, [BASE+8]                // Caveat: CARG3d == BASE.
  2802.   //|  mov CARG1d, L:RB
  2803.   //|.else
  2804.   //|  mov TAB:RD, [BASE]
  2805.   //|  mov ARG2, TAB:RD
  2806.   //|  mov ARG1, L:RB
  2807.   //|  add BASE, 8
  2808.   //|  mov ARG3, BASE
  2809.   //|.endif
  2810.   //|  mov SAVE_PC, PC                        // Needed for ITERN fallback.
  2811.   //|  call extern lj_tab_next        // (lua_State *L, GCtab *t, TValue *key)
  2812.   //|  // Flag returned in eax (RD).
  2813.   //|  mov BASE, L:RB->base
  2814.   //|  test RD, RD;  jz >3                // End of traversal?
  2815.   //|  // Copy key and value to results.
  2816.   //|.if X64
  2817.   //|  mov RBa, [BASE+8]
  2818.   //|  mov RDa, [BASE+16]
  2819.   //|  mov [BASE-8], RBa
  2820.   //|  mov [BASE], RDa
  2821.   //|.else
  2822.   //|  mov RB, [BASE+8]
  2823.   //|  mov RD, [BASE+12]
  2824.   //|  mov [BASE-8], RB
  2825.   //|  mov [BASE-4], RD
  2826.   //|  mov RB, [BASE+16]
  2827.   //|  mov RD, [BASE+20]
  2828.   //|  mov [BASE], RB
  2829.   //|  mov [BASE+4], RD
  2830.   //|.endif
  2831.   //|->fff_res2:
  2832.   //|  mov RD, 1+2
  2833.   //|  jmp ->fff_res
  2834.   //|2:  // Set missing 2nd arg to nil.
  2835.   //|  mov dword [BASE+12], LJ_TNIL
  2836.   //|  jmp <1
  2837.   //|3:  // End of traversal: return nil.
  2838.   //|  mov dword [BASE-4], LJ_TNIL
  2839.   dasm_put(Dst, 2566, LJ_TTAB, Dt1(->base), Dt1(->top), Dt1(->base), 1+2, LJ_TNIL);
  2840. #line 1633 "vm_x86.dasc"
  2841.   //|  jmp ->fff_res1
  2842.   //|
  2843.   //|.ffunc_1 pairs
  2844.   //|  mov TAB:RB, [BASE]
  2845.   //|  cmp dword [BASE+4], LJ_TTAB;  jne ->fff_fallback
  2846.   dasm_put(Dst, 2657, LJ_TNIL, 1+1, LJ_TTAB);
  2847. #line 1638 "vm_x86.dasc"
  2848. #if LJ_52
  2849.   //|  cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
  2850.   dasm_put(Dst, 2688, Dt6(->metatable));
  2851. #line 1640 "vm_x86.dasc"
  2852. #endif
  2853.   //|  mov CFUNC:RB, [BASE-8]
  2854.   //|  mov CFUNC:RD, CFUNC:RB->upvalue[0]
  2855.   //|  mov PC, [BASE-4]
  2856.   //|  mov dword [BASE-4], LJ_TFUNC
  2857.   //|  mov [BASE-8], CFUNC:RD
  2858.   //|  mov dword [BASE+12], LJ_TNIL
  2859.   //|  mov RD, 1+3
  2860.   //|  jmp ->fff_res
  2861.   //|
  2862.   //|.ffunc_2 ipairs_aux
  2863.   //|  cmp dword [BASE+4], LJ_TTAB;  jne ->fff_fallback
  2864.   //|  cmp dword [BASE+12], LJ_TISNUM
  2865.   //|.if DUALNUM
  2866.   //|  jne ->fff_fallback
  2867.   //|.else
  2868.   //|  jae ->fff_fallback
  2869.   //|.endif
  2870.   //|  mov PC, [BASE-4]
  2871.   //|.if DUALNUM
  2872.   //|  mov RD, dword [BASE+8]
  2873.   //|  add RD, 1
  2874.   //|  mov dword [BASE-4], LJ_TISNUM
  2875.   //|  mov dword [BASE-8], RD
  2876.   //|.else
  2877.   //|  movsd xmm0, qword [BASE+8]
  2878.   //|  sseconst_1 xmm1, RBa
  2879.   //|  addsd xmm0, xmm1
  2880.   //|  cvttsd2si RD, xmm0
  2881.   //|  movsd qword [BASE-8], xmm0
  2882.   //|.endif
  2883.   //|  mov TAB:RB, [BASE]
  2884.   //|  cmp RD, TAB:RB->asize;  jae >2        // Not in array part?
  2885.   //|  shl RD, 3
  2886.   dasm_put(Dst, 2697, Dt8(->upvalue[0]), LJ_TFUNC, LJ_TNIL, 1+3, 2+1, LJ_TTAB, LJ_TISNUM, LJ_TISNUM, Dt6(->asize));
  2887. #line 1674 "vm_x86.dasc"
  2888.   //|  add RD, TAB:RB->array
  2889.   //|1:
  2890.   //|  cmp dword [RD+4], LJ_TNIL;  je ->fff_res0
  2891.   //|  // Copy array slot.
  2892.   //|.if X64
  2893.   //|  mov RBa, [RD]
  2894.   //|  mov [BASE], RBa
  2895.   //|.else
  2896.   //|  mov RB, [RD]
  2897.   //|  mov RD, [RD+4]
  2898.   //|  mov [BASE], RB
  2899.   //|  mov [BASE+4], RD
  2900.   //|.endif
  2901.   //|  jmp ->fff_res2
  2902.   //|2:  // Check for empty hash part first. Otherwise call C function.
  2903.   //|  cmp dword TAB:RB->hmask, 0; je ->fff_res0
  2904.   //|  mov FCARG1, TAB:RB
  2905.   //|  mov RB, BASE                        // Save BASE.
  2906.   //|  mov FCARG2, RD                        // Caveat: FCARG2 == BASE
  2907.   //|  call extern lj_tab_getinth@8        // (GCtab *t, int32_t key)
  2908.   //|  // cTValue * or NULL returned in eax (RD).
  2909.   //|  mov BASE, RB
  2910.   //|  test RD, RD
  2911.   //|  jnz <1
  2912.   //|->fff_res0:
  2913.   //|  mov RD, 1+0
  2914.   //|  jmp ->fff_res
  2915.   //|
  2916.   //|.ffunc_1 ipairs
  2917.   //|  mov TAB:RB, [BASE]
  2918.   dasm_put(Dst, 2784, Dt6(->array), LJ_TNIL, Dt6(->hmask), 1+0, 1+1);
  2919. #line 1704 "vm_x86.dasc"
  2920.   //|  cmp dword [BASE+4], LJ_TTAB;  jne ->fff_fallback
  2921.   dasm_put(Dst, 2676, LJ_TTAB);
  2922. #line 1705 "vm_x86.dasc"
  2923. #if LJ_52
  2924.   //|  cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
  2925.   dasm_put(Dst, 2688, Dt6(->metatable));
  2926. #line 1707 "vm_x86.dasc"
  2927. #endif
  2928.   //|  mov CFUNC:RB, [BASE-8]
  2929.   //|  mov CFUNC:RD, CFUNC:RB->upvalue[0]
  2930.   //|  mov PC, [BASE-4]
  2931.   //|  mov dword [BASE-4], LJ_TFUNC
  2932.   //|  mov [BASE-8], CFUNC:RD
  2933.   //|.if DUALNUM
  2934.   //|  mov dword [BASE+12], LJ_TISNUM
  2935.   //|  mov dword [BASE+8], 0
  2936.   //|.else
  2937.   //|  xorps xmm0, xmm0
  2938.   //|  movsd qword [BASE+8], xmm0
  2939.   //|.endif
  2940.   //|  mov RD, 1+3
  2941.   //|  jmp ->fff_res
  2942.   //|
  2943.   //|//-- Base library: catch errors ----------------------------------------
  2944.   //|
  2945.   //|.ffunc_1 pcall
  2946.   //|  lea RA, [BASE+8]
  2947.   //|  sub NARGS:RD, 1
  2948.   //|  mov PC, 8+FRAME_PCALL
  2949.   //|1:
  2950.   //|  movzx RB, byte [DISPATCH+DISPATCH_GL(hookmask)]
  2951.   //|  shr RB, HOOK_ACTIVE_SHIFT
  2952.   //|  and RB, 1
  2953.   //|  add PC, RB                                // Remember active hook before pcall.
  2954.   //|  jmp ->vm_call_dispatch
  2955.   //|
  2956.   //|.ffunc_2 xpcall
  2957.   //|  cmp dword [BASE+12], LJ_TFUNC;  jne ->fff_fallback
  2958.   dasm_put(Dst, 2860, Dt8(->upvalue[0]), LJ_TFUNC, LJ_TISNUM, 1+3, 1+1, 8+FRAME_PCALL, DISPATCH_GL(hookmask), HOOK_ACTIVE_SHIFT, 2+1);
  2959. #line 1738 "vm_x86.dasc"
  2960.   //|  mov RB, [BASE+4]                        // Swap function and traceback.
  2961.   //|  mov [BASE+12], RB
  2962.   //|  mov dword [BASE+4], LJ_TFUNC
  2963.   //|  mov LFUNC:RB, [BASE]
  2964.   //|  mov PC, [BASE+8]
  2965.   //|  mov [BASE+8], LFUNC:RB
  2966.   //|  mov [BASE], PC
  2967.   //|  lea RA, [BASE+16]
  2968.   //|  sub NARGS:RD, 2
  2969.   //|  mov PC, 16+FRAME_PCALL
  2970.   //|  jmp <1
  2971.   //|
  2972.   //|//-- Coroutine library --------------------------------------------------
  2973.   //|
  2974.   //|.macro coroutine_resume_wrap, resume
  2975.   //|.if resume
  2976.   //|.ffunc_1 coroutine_resume
  2977.   //|  mov L:RB, [BASE]
  2978.   //|.else
  2979.   //|.ffunc coroutine_wrap_aux
  2980.   //|  mov CFUNC:RB, [BASE-8]
  2981.   //|  mov L:RB, CFUNC:RB->upvalue[0].gcr
  2982.   //|.endif
  2983.   //|  mov PC, [BASE-4]
  2984.   //|  mov SAVE_PC, PC
  2985.   //|.if X64
  2986.   //|  mov TMP1, L:RB
  2987.   //|.else
  2988.   //|  mov ARG1, L:RB
  2989.   //|.endif
  2990.   //|.if resume
  2991.   //|  cmp dword [BASE+4], LJ_TTHREAD;  jne ->fff_fallback
  2992.   //|.endif
  2993.   //|  cmp aword L:RB->cframe, 0; jne ->fff_fallback
  2994.   //|  cmp byte L:RB->status, LUA_YIELD;  ja ->fff_fallback
  2995.   //|  mov RA, L:RB->top
  2996.   //|  je >1                                // Status != LUA_YIELD (i.e. 0)?
  2997.   //|  cmp RA, L:RB->base                        // Check for presence of initial func.
  2998.   //|  je ->fff_fallback
  2999.   //|1:
  3000.   //|.if resume
  3001.   //|  lea PC, [RA+NARGS:RD*8-16]                // Check stack space (-1-thread).
  3002.   //|.else
  3003.   //|  lea PC, [RA+NARGS:RD*8-8]                // Check stack space (-1).
  3004.   //|.endif
  3005.   //|  cmp PC, L:RB->maxstack; ja ->fff_fallback
  3006.   //|  mov L:RB->top, PC
  3007.   //|
  3008.   //|  mov L:RB, SAVE_L
  3009.   //|  mov L:RB->base, BASE
  3010.   //|.if resume
  3011.   //|  add BASE, 8                        // Keep resumed thread in stack for GC.
  3012.   //|.endif
  3013.   //|  mov L:RB->top, BASE
  3014.   //|.if resume
  3015.   //|  lea RB, [BASE+NARGS:RD*8-24]        // RB = end of source for stack move.
  3016.   //|.else
  3017.   //|  lea RB, [BASE+NARGS:RD*8-16]        // RB = end of source for stack move.
  3018.   //|.endif
  3019.   //|  sub RBa, PCa                        // Relative to PC.
  3020.   //|
  3021.   //|  cmp PC, RA
  3022.   //|  je >3
  3023.   //|2:  // Move args to coroutine.
  3024.   //|.if X64
  3025.   //|  mov RCa, [PC+RB]
  3026.   //|  mov [PC-8], RCa
  3027.   //|.else
  3028.   //|  mov RC, [PC+RB+4]
  3029.   //|  mov [PC-4], RC
  3030.   //|  mov RC, [PC+RB]
  3031.   //|  mov [PC-8], RC
  3032.   //|.endif
  3033.   //|  sub PC, 8
  3034.   //|  cmp PC, RA
  3035.   //|  jne <2
  3036.   //|3:
  3037.   //|.if X64
  3038.   //|  mov CARG2d, RA
  3039.   //|  mov CARG1d, TMP1
  3040.   //|.else
  3041.   //|  mov ARG2, RA
  3042.   //|  xor RA, RA
  3043.   //|  mov ARG4, RA
  3044.   //|  mov ARG3, RA
  3045.   //|.endif
  3046.   //|  call ->vm_resume                        // (lua_State *L, TValue *base, 0, 0)
  3047.   //|
  3048.   //|  mov L:RB, SAVE_L
  3049.   //|.if X64
  3050.   //|  mov L:PC, TMP1
  3051.   //|.else
  3052.   //|  mov L:PC, ARG1                        // The callee doesn't modify SAVE_L.
  3053.   //|.endif
  3054.   //|  mov BASE, L:RB->base
  3055.   //|  mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
  3056.   //|  set_vmstate INTERP
  3057.   //|
  3058.   //|  cmp eax, LUA_YIELD
  3059.   //|  ja >8
  3060.   //|4:
  3061.   //|  mov RA, L:PC->base
  3062.   //|  mov KBASE, L:PC->top
  3063.   //|  mov L:PC->top, RA                        // Clear coroutine stack.
  3064.   //|  mov PC, KBASE
  3065.   //|  sub PC, RA
  3066.   //|  je >6                                // No results?
  3067.   //|  lea RD, [BASE+PC]
  3068.   //|  shr PC, 3
  3069.   //|  cmp RD, L:RB->maxstack
  3070.   //|  ja >9                                // Need to grow stack?
  3071.   //|
  3072.   //|  mov RB, BASE
  3073.   //|  sub RBa, RAa
  3074.   //|5:  // Move results from coroutine.
  3075.   //|.if X64
  3076.   //|  mov RDa, [RA]
  3077.   //|  mov [RA+RB], RDa
  3078.   //|.else
  3079.   //|  mov RD, [RA]
  3080.   //|  mov [RA+RB], RD
  3081.   //|  mov RD, [RA+4]
  3082.   //|  mov [RA+RB+4], RD
  3083.   //|.endif
  3084.   //|  add RA, 8
  3085.   //|  cmp RA, KBASE
  3086.   //|  jne <5
  3087.   //|6:
  3088.   //|.if resume
  3089.   //|  lea RD, [PC+2]                        // nresults+1 = 1 + true + results.
  3090.   //|  mov dword [BASE-4], LJ_TTRUE        // Prepend true to results.
  3091.   //|.else
  3092.   //|  lea RD, [PC+1]                        // nresults+1 = 1 + results.
  3093.   //|.endif
  3094.   //|7:
  3095.   //|  mov PC, SAVE_PC
  3096.   //|  mov MULTRES, RD
  3097.   //|.if resume
  3098.   //|  mov RAa, -8
  3099.   //|.else
  3100.   //|  xor RA, RA
  3101.   //|.endif
  3102.   //|  test PC, FRAME_TYPE
  3103.   //|  jz ->BC_RET_Z
  3104.   //|  jmp ->vm_return
  3105.   //|
  3106.   //|8:  // Coroutine returned with error (at co->top-1).
  3107.   //|.if resume
  3108.   //|  mov dword [BASE-4], LJ_TFALSE        // Prepend false to results.
  3109.   //|  mov RA, L:PC->top
  3110.   //|  sub RA, 8
  3111.   //|  mov L:PC->top, RA                        // Clear error from coroutine stack.
  3112.   //|  // Copy error message.
  3113.   //|.if X64
  3114.   //|  mov RDa, [RA]
  3115.   //|  mov [BASE], RDa
  3116.   //|.else
  3117.   //|  mov RD, [RA]
  3118.   //|  mov [BASE], RD
  3119.   //|  mov RD, [RA+4]
  3120.   //|  mov [BASE+4], RD
  3121.   //|.endif
  3122.   //|  mov RD, 1+2                        // nresults+1 = 1 + false + error.
  3123.   //|  jmp <7
  3124.   //|.else
  3125.   //|  mov FCARG2, L:PC
  3126.   //|  mov FCARG1, L:RB
  3127.   //|  call extern lj_ffh_coroutine_wrap_err@8  // (lua_State *L, lua_State *co)
  3128.   //|  // Error function does not return.
  3129.   //|.endif
  3130.   //|
  3131.   //|9:  // Handle stack expansion on return from yield.
  3132.   //|.if X64
  3133.   //|  mov L:RA, TMP1
  3134.   //|.else
  3135.   //|  mov L:RA, ARG1                        // The callee doesn't modify SAVE_L.
  3136.   //|.endif
  3137.   //|  mov L:RA->top, KBASE                // Undo coroutine stack clearing.
  3138.   //|  mov FCARG2, PC
  3139.   //|  mov FCARG1, L:RB
  3140.   //|  call extern lj_state_growstack@8        // (lua_State *L, int n)
  3141.   //|.if X64
  3142.   //|  mov L:PC, TMP1
  3143.   //|.else
  3144.   //|  mov L:PC, ARG1
  3145.   //|.endif
  3146.   //|  mov BASE, L:RB->base
  3147.   //|  jmp <4                                // Retry the stack move.
  3148.   //|.endmacro
  3149.   //|
  3150.   //|  coroutine_resume_wrap 1                // coroutine.resume
  3151.   dasm_put(Dst, 2947, LJ_TFUNC, LJ_TFUNC, 16+FRAME_PCALL, 1+1, LJ_TTHREAD, Dt1(->cframe), Dt1(->status), LUA_YIELD);
  3152.   dasm_put(Dst, 3038, Dt1(->top), Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top));
  3153.   dasm_put(Dst, 3127, Dt1(->base), DISPATCH_GL(cur_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack));
  3154. #line 1929 "vm_x86.dasc"
  3155.   //|  coroutine_resume_wrap 0                // coroutine.wrap
  3156.   dasm_put(Dst, 3218, LJ_TTRUE, FRAME_TYPE, LJ_TFALSE, Dt1(->top), Dt1(->top), 1+2, Dt1(->top), Dt1(->base));
  3157.   dasm_put(Dst, 3319, Dt8(->upvalue[0].gcr), Dt1(->cframe), Dt1(->status), LUA_YIELD, Dt1(->top), Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base));
  3158.   dasm_put(Dst, 3393, Dt1(->top), Dt1(->base), DISPATCH_GL(cur_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top));
  3159. #line 1930 "vm_x86.dasc"
  3160.   //|
  3161.   //|.ffunc coroutine_yield
  3162.   //|  mov L:RB, SAVE_L
  3163.   dasm_put(Dst, 3481, Dt1(->maxstack), FRAME_TYPE, Dt1(->top), Dt1(->base));
  3164. #line 1933 "vm_x86.dasc"
  3165.   //|  test aword L:RB->cframe, CFRAME_RESUME
  3166.   //|  jz ->fff_fallback
  3167.   //|  mov L:RB->base, BASE
  3168.   //|  lea RD, [BASE+NARGS:RD*8-8]
  3169.   //|  mov L:RB->top, RD
  3170.   //|  xor RD, RD
  3171.   //|  mov aword L:RB->cframe, RDa
  3172.   //|  mov al, LUA_YIELD
  3173.   //|  mov byte L:RB->status, al
  3174.   //|  jmp ->vm_leave_unw
  3175.   //|
  3176.   //|//-- Math library -------------------------------------------------------
  3177.   //|
  3178.   //|.if not DUALNUM
  3179.   //|->fff_resi:  // Dummy.
  3180.   //|.endif
  3181.   //|
  3182.   //|->fff_resn:
  3183.   //|  mov PC, [BASE-4]
  3184.   //|  fstp qword [BASE-8]
  3185.   //|  jmp ->fff_res1
  3186.   //|
  3187.   //|  .ffunc_1 math_abs
  3188.   //|.if DUALNUM
  3189.   //|  cmp dword [BASE+4], LJ_TISNUM; jne >2
  3190.   //|  mov RB, dword [BASE]
  3191.   dasm_put(Dst, 3601, Dt1(->cframe), CFRAME_RESUME, Dt1(->base), Dt1(->top), Dt1(->cframe), LUA_YIELD, Dt1(->status), 1+1, LJ_TISNUM);
  3192. #line 1959 "vm_x86.dasc"
  3193.   //|  cmp RB, 0; jns ->fff_resi
  3194.   //|  neg RB; js >1
  3195.   //|->fff_resbit:
  3196.   //|->fff_resi:
  3197.   //|  mov PC, [BASE-4]
  3198.   //|  mov dword [BASE-4], LJ_TISNUM
  3199.   //|  mov dword [BASE-8], RB
  3200.   //|  jmp ->fff_res1
  3201.   //|1:
  3202.   //|  mov PC, [BASE-4]
  3203.   //|  mov dword [BASE-4], 0x41e00000  // 2^31.
  3204.   //|  mov dword [BASE-8], 0
  3205.   //|  jmp ->fff_res1
  3206.   //|2:
  3207.   //|  ja ->fff_fallback
  3208.   //|.else
  3209.   //|  cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
  3210.   //|.endif
  3211.   //|  movsd xmm0, qword [BASE]
  3212.   //|  sseconst_abs xmm1, RDa
  3213.   //|  andps xmm0, xmm1
  3214.   //|->fff_resxmm0:
  3215.   //|  mov PC, [BASE-4]
  3216.   //|  movsd qword [BASE-8], xmm0
  3217.   //|  // fallthrough
  3218.   //|
  3219.   //|->fff_res1:
  3220.   //|  mov RD, 1+1
  3221.   //|->fff_res:
  3222.   //|  mov MULTRES, RD
  3223.   dasm_put(Dst, 3675, LJ_TISNUM, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), 1+1);
  3224. #line 1989 "vm_x86.dasc"
  3225.   //|->fff_res_:
  3226.   //|  test PC, FRAME_TYPE
  3227.   //|  jnz >7
  3228.   //|5:
  3229.   //|  cmp PC_RB, RDL                        // More results expected?
  3230.   //|  ja >6
  3231.   //|  // Adjust BASE. KBASE is assumed to be set for the calling frame.
  3232.   //|  movzx RA, PC_RA
  3233.   //|  not RAa                                // Note: ~RA = -(RA+1)
  3234.   //|  lea BASE, [BASE+RA*8]                // base = base - (RA+1)*8
  3235.   //|  ins_next
  3236.   //|
  3237.   //|6:  // Fill up results with nil.
  3238.   //|  mov dword [BASE+RD*8-12], LJ_TNIL
  3239.   //|  add RD, 1
  3240.   //|  jmp <5
  3241.   //|
  3242.   //|7:  // Non-standard return case.
  3243.   //|  mov RAa, -8                        // Results start at BASE+RA = BASE-8.
  3244.   //|  jmp ->vm_return
  3245.   //|
  3246.   //|.if X64
  3247.   //|.define fff_resfp, fff_resxmm0
  3248.   //|.else
  3249.   //|.define fff_resfp, fff_resn
  3250.   //|.endif
  3251.   //|
  3252.   //|.macro math_round, func
  3253.   //|  .ffunc math_ .. func
  3254.   //|.if DUALNUM
  3255.   //|  cmp dword [BASE+4], LJ_TISNUM; jne >1
  3256.   //|  mov RB, dword [BASE]; jmp ->fff_resi
  3257.   //|1:
  3258.   //|  ja ->fff_fallback
  3259.   //|.else
  3260.   //|  cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
  3261.   //|.endif
  3262.   //|  movsd xmm0, qword [BASE]
  3263.   //|  call ->vm_ .. func .. _sse
  3264.   //|.if DUALNUM
  3265.   //|  cvttsd2si RB, xmm0
  3266.   //|  cmp RB, 0x80000000
  3267.   //|  jne ->fff_resi
  3268.   //|  cvtsi2sd xmm1, RB
  3269.   //|  ucomisd xmm0, xmm1
  3270.   //|  jp ->fff_resxmm0
  3271.   //|  je ->fff_resi
  3272.   //|.endif
  3273.   //|  jmp ->fff_resxmm0
  3274.   //|.endmacro
  3275.   //|
  3276.   //|  math_round floor
  3277.   dasm_put(Dst, 3782, FRAME_TYPE, LJ_TNIL, LJ_TISNUM);
  3278. #line 2041 "vm_x86.dasc"
  3279.   //|  math_round ceil
  3280.   dasm_put(Dst, 3890, LJ_TISNUM);
  3281. #line 2042 "vm_x86.dasc"
  3282.   //|
  3283.   //|.ffunc_nsse math_sqrt, sqrtsd; jmp ->fff_resxmm0
  3284.   //|
  3285.   //|.ffunc math_log
  3286.   //|  cmp NARGS:RD, 1+1; jne ->fff_fallback        // Exactly one argument.
  3287.   dasm_put(Dst, 3963, 1+1, LJ_TISNUM);
  3288. #line 2047 "vm_x86.dasc"
  3289.   //|  cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
  3290.   //|  movsd xmm0, qword [BASE]
  3291.   //|.if not X64
  3292.   //|  movsd FPARG1, xmm0
  3293.   //|.endif
  3294.   //|  mov RB, BASE
  3295.   //|  call extern log
  3296.   //|  mov BASE, RB
  3297.   //|  jmp ->fff_resfp
  3298.   //|
  3299.   //|.macro math_extern, func
  3300.   //|  .ffunc_nsse math_ .. func
  3301.   //|.if not X64
  3302.   //|  movsd FPARG1, xmm0
  3303.   //|.endif
  3304.   //|  mov RB, BASE
  3305.   //|  call extern func
  3306.   //|  mov BASE, RB
  3307.   //|  jmp ->fff_resfp
  3308.   //|.endmacro
  3309.   //|
  3310.   //|.macro math_extern2, func
  3311.   //|  .ffunc_nnsse math_ .. func
  3312.   //|.if not X64
  3313.   //|  movsd FPARG1, xmm0
  3314.   //|  movsd FPARG3, xmm1
  3315.   //|.endif
  3316.   //|  mov RB, BASE
  3317.   //|  call extern func
  3318.   //|  mov BASE, RB
  3319.   //|  jmp ->fff_resfp
  3320.   //|.endmacro
  3321.   //|
  3322.   //|  math_extern log10
  3323.   //|  math_extern exp
  3324.   dasm_put(Dst, 4039, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
  3325. #line 2082 "vm_x86.dasc"
  3326.   //|  math_extern sin
  3327.   //|  math_extern cos
  3328.   dasm_put(Dst, 4122, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
  3329. #line 2084 "vm_x86.dasc"
  3330.   //|  math_extern tan
  3331.   //|  math_extern asin
  3332.   //|  math_extern acos
  3333.   dasm_put(Dst, 4206, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
  3334. #line 2087 "vm_x86.dasc"
  3335.   //|  math_extern atan
  3336.   //|  math_extern sinh
  3337.   dasm_put(Dst, 4301, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
  3338. #line 2089 "vm_x86.dasc"
  3339.   //|  math_extern cosh
  3340.   //|  math_extern tanh
  3341.   dasm_put(Dst, 4384, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
  3342. #line 2091 "vm_x86.dasc"
  3343.   //|  math_extern2 pow
  3344.   //|  math_extern2 atan2
  3345.   dasm_put(Dst, 4468, 2+1, LJ_TISNUM, LJ_TISNUM, 2+1, LJ_TISNUM);
  3346. #line 2093 "vm_x86.dasc"
  3347.   //|  math_extern2 fmod
  3348.   //|
  3349.   //|.ffunc_nnr math_ldexp;        fscale; fpop1;        jmp ->fff_resn
  3350.   dasm_put(Dst, 4558, LJ_TISNUM, 2+1, LJ_TISNUM, LJ_TISNUM, 2+1);
  3351. #line 2096 "vm_x86.dasc"
  3352.   //|
  3353.   //|.ffunc_1 math_frexp
  3354.   //|  mov RB, [BASE+4]
  3355.   //|  cmp RB, LJ_TISNUM;  jae ->fff_fallback
  3356.   //|  mov PC, [BASE-4]
  3357.   //|  mov RC, [BASE]
  3358.   //|  mov [BASE-4], RB; mov [BASE-8], RC
  3359.   //|  shl RB, 1; cmp RB, 0xffe00000; jae >3
  3360.   //|  or RC, RB; jz >3
  3361.   //|  mov RC, 1022
  3362.   //|  cmp RB, 0x00200000; jb >4
  3363.   //|1:
  3364.   //|  shr RB, 21; sub RB, RC                // Extract and unbias exponent.
  3365.   dasm_put(Dst, 4654, LJ_TISNUM, LJ_TISNUM, 1+1, LJ_TISNUM);
  3366. #line 2109 "vm_x86.dasc"
  3367.   //|  cvtsi2sd xmm0, RB
  3368.   //|  mov RB, [BASE-4]
  3369.   //|  and RB, 0x800fffff                        // Mask off exponent.
  3370.   //|  or RB, 0x3fe00000                        // Put mantissa in range [0.5,1) or 0.
  3371.   //|  mov [BASE-4], RB
  3372.   //|2:
  3373.   //|  movsd qword [BASE], xmm0
  3374.   //|  mov RD, 1+2
  3375.   //|  jmp ->fff_res
  3376.   //|3:  // Return +-0, +-Inf, NaN unmodified and an exponent of 0.
  3377.   //|  xorps xmm0, xmm0; jmp <2
  3378.   //|4:  // Handle denormals by multiplying with 2^54 and adjusting the bias.
  3379.   //|  movsd xmm0, qword [BASE]
  3380.   //|  sseconst_hi xmm1, RBa, 43500000  // 2^54.
  3381.   //|  mulsd xmm0, xmm1
  3382.   //|  movsd qword [BASE-8], xmm0
  3383.   //|  mov RB, [BASE-4]; mov RC, 1076; shl RB, 1; jmp <1
  3384.   //|
  3385.   //|.ffunc_nsse math_modf
  3386.   //|  mov RB, [BASE+4]
  3387.   //|  mov PC, [BASE-4]
  3388.   //|  shl RB, 1; cmp RB, 0xffe00000; je >4        // +-Inf?
  3389.   //|  movaps xmm4, xmm0
  3390.   dasm_put(Dst, 4761, 1+2, (unsigned int)(U64x(43500000,00000000)), (unsigned int)((U64x(43500000,00000000))>>32), 1+1, LJ_TISNUM);
  3391. #line 2132 "vm_x86.dasc"
  3392.   //|  call ->vm_trunc_sse
  3393.   //|  subsd xmm4, xmm0
  3394.   //|1:
  3395.   //|  movsd qword [BASE-8], xmm0
  3396.   //|  movsd qword [BASE], xmm4
  3397.   //|  mov RC, [BASE-4]; mov RB, [BASE+4]
  3398.   //|  xor RC, RB; js >3                                // Need to adjust sign?
  3399.   //|2:
  3400.   //|  mov RD, 1+2
  3401.   //|  jmp ->fff_res
  3402.   //|3:
  3403.   //|  xor RB, 0x80000000; mov [BASE+4], RB        // Flip sign of fraction.
  3404.   //|  jmp <2
  3405.   //|4:
  3406.   //|  xorps xmm4, xmm4; jmp <1                        // Return +-Inf and +-0.
  3407.   //|
  3408.   //|.macro math_minmax, name, cmovop, sseop
  3409.   //|  .ffunc name
  3410.   //|  mov RA, 2
  3411.   //|  cmp dword [BASE+4], LJ_TISNUM
  3412.   //|.if DUALNUM
  3413.   //|  jne >4
  3414.   //|  mov RB, dword [BASE]
  3415.   //|1:  // Handle integers.
  3416.   //|  cmp RA, RD; jae ->fff_resi
  3417.   //|  cmp dword [BASE+RA*8-4], LJ_TISNUM; jne >3
  3418.   //|  cmp RB, dword [BASE+RA*8-8]
  3419.   //|  cmovop RB, dword [BASE+RA*8-8]
  3420.   //|  add RA, 1
  3421.   //|  jmp <1
  3422.   //|3:
  3423.   //|  ja ->fff_fallback
  3424.   //|  // Convert intermediate result to number and continue below.
  3425.   //|  cvtsi2sd xmm0, RB
  3426.   //|  jmp >6
  3427.   //|4:
  3428.   //|  ja ->fff_fallback
  3429.   //|.else
  3430.   //|  jae ->fff_fallback
  3431.   //|.endif
  3432.   //|
  3433.   //|  movsd xmm0, qword [BASE]
  3434.   //|5:  // Handle numbers or integers.
  3435.   //|  cmp RA, RD; jae ->fff_resxmm0
  3436.   //|  cmp dword [BASE+RA*8-4], LJ_TISNUM
  3437.   //|.if DUALNUM
  3438.   //|  jb >6
  3439.   //|  ja ->fff_fallback
  3440.   //|  cvtsi2sd xmm1, dword [BASE+RA*8-8]
  3441.   //|  jmp >7
  3442.   //|.else
  3443.   //|  jae ->fff_fallback
  3444.   //|.endif
  3445.   //|6:
  3446.   //|  movsd xmm1, qword [BASE+RA*8-8]
  3447.   //|7:
  3448.   //|  sseop xmm0, xmm1
  3449.   //|  add RA, 1
  3450.   //|  jmp <5
  3451.   //|.endmacro
  3452.   //|
  3453.   //|  math_minmax math_min, cmovg, minsd
  3454.   dasm_put(Dst, 4905, 1+2, LJ_TISNUM);
  3455.   dasm_put(Dst, 4997, LJ_TISNUM, LJ_TISNUM);
  3456. #line 2194 "vm_x86.dasc"
  3457.   //|  math_minmax math_max, cmovl, maxsd
  3458.   dasm_put(Dst, 5078, LJ_TISNUM, LJ_TISNUM);
  3459. #line 2195 "vm_x86.dasc"
  3460.   //|
  3461.   //|//-- String library -----------------------------------------------------
  3462.   //|
  3463.   //|.ffunc string_byte                        // Only handle the 1-arg case here.
  3464.   //|  cmp NARGS:RD, 1+1;  jne ->fff_fallback
  3465.   dasm_put(Dst, 5176, LJ_TISNUM);
  3466. #line 2200 "vm_x86.dasc"
  3467.   //|  cmp dword [BASE+4], LJ_TSTR;  jne ->fff_fallback
  3468.   //|  mov STR:RB, [BASE]
  3469.   //|  mov PC, [BASE-4]
  3470.   //|  cmp dword STR:RB->len, 1
  3471.   //|  jb ->fff_res0                        // Return no results for empty string.
  3472.   //|  movzx RB, byte STR:RB[1]
  3473.   //|.if DUALNUM
  3474.   //|  jmp ->fff_resi
  3475.   //|.else
  3476.   //|  cvtsi2sd xmm0, RB; jmp ->fff_resxmm0
  3477.   //|.endif
  3478.   //|
  3479.   //|.ffunc string_char                        // Only handle the 1-arg case here.
  3480.   //|  ffgccheck
  3481.   //|  cmp NARGS:RD, 1+1;  jne ->fff_fallback        // *Exactly* 1 arg.
  3482.   dasm_put(Dst, 5262, 1+1, LJ_TSTR, Dt5(->len), Dt5([1]), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
  3483. #line 2215 "vm_x86.dasc"
  3484.   //|  cmp dword [BASE+4], LJ_TISNUM
  3485.   //|.if DUALNUM
  3486.   //|  jne ->fff_fallback
  3487.   //|  mov RB, dword [BASE]
  3488.   //|  cmp RB, 255;  ja ->fff_fallback
  3489.   //|  mov TMP2, RB
  3490.   //|.else
  3491.   //|  jae ->fff_fallback
  3492.   //|  cvttsd2si RB, qword [BASE]
  3493.   //|  cmp RB, 255;  ja ->fff_fallback
  3494.   //|  mov TMP2, RB
  3495.   //|.endif
  3496.   //|.if X64
  3497.   //|  mov TMP3, 1
  3498.   //|.else
  3499.   //|  mov ARG3, 1
  3500.   //|.endif
  3501.   //|  lea RDa, TMP2                        // Points to stack. Little-endian.
  3502.   //|->fff_newstr:
  3503.   //|  mov L:RB, SAVE_L
  3504.   //|  mov L:RB->base, BASE
  3505.   //|.if X64
  3506.   //|  mov CARG3d, TMP3                        // Zero-extended to size_t.
  3507.   //|  mov CARG2, RDa                        // May be 64 bit ptr to stack.
  3508.   //|  mov CARG1d, L:RB
  3509.   //|.else
  3510.   //|  mov ARG2, RD
  3511.   //|  mov ARG1, L:RB
  3512.   //|.endif
  3513.   //|  mov SAVE_PC, PC
  3514.   //|  call extern lj_str_new                // (lua_State *L, char *str, size_t l)
  3515.   //|->fff_resstr:
  3516.   //|  // GCstr * returned in eax (RD).
  3517.   //|  mov BASE, L:RB->base
  3518.   //|  mov PC, [BASE-4]
  3519.   //|  mov dword [BASE-4], LJ_TSTR
  3520.   //|  mov [BASE-8], STR:RD
  3521.   //|  jmp ->fff_res1
  3522.   //|
  3523.   //|.ffunc string_sub
  3524.   //|  ffgccheck
  3525.   dasm_put(Dst, 5321, 1+1, LJ_TISNUM, Dt1(->base), Dt1(->base), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
  3526. #line 2256 "vm_x86.dasc"
  3527.   //|  mov TMP2, -1
  3528.   //|  cmp NARGS:RD, 1+2;  jb ->fff_fallback
  3529.   //|  jna >1
  3530.   //|  cmp dword [BASE+20], LJ_TISNUM
  3531.   //|.if DUALNUM
  3532.   //|  jne ->fff_fallback
  3533.   //|  mov RB, dword [BASE+16]
  3534.   //|  mov TMP2, RB
  3535.   //|.else
  3536.   //|  jae ->fff_fallback
  3537.   //|  cvttsd2si RB, qword [BASE+16]
  3538.   //|  mov TMP2, RB
  3539.   //|.endif
  3540.   //|1:
  3541.   //|  cmp dword [BASE+4], LJ_TSTR;  jne ->fff_fallback
  3542.   //|  cmp dword [BASE+12], LJ_TISNUM
  3543.   //|.if DUALNUM
  3544.   //|  jne ->fff_fallback
  3545.   //|.else
  3546.   //|  jae ->fff_fallback
  3547.   //|.endif
  3548.   //|  mov STR:RB, [BASE]
  3549.   //|  mov TMP3, STR:RB
  3550.   //|  mov RB, STR:RB->len
  3551.   //|.if DUALNUM
  3552.   //|  mov RA, dword [BASE+8]
  3553.   //|.else
  3554.   //|  cvttsd2si RA, qword [BASE+8]
  3555.   //|.endif
  3556.   //|  mov RC, TMP2
  3557.   //|  cmp RB, RC                                // len < end? (unsigned compare)
  3558.   //|  jb >5
  3559.   //|2:
  3560.   //|  test RA, RA                        // start <= 0?
  3561.   dasm_put(Dst, 5433, 1+2, LJ_TISNUM, LJ_TSTR, LJ_TISNUM, Dt5(->len));
  3562. #line 2290 "vm_x86.dasc"
  3563.   //|  jle >7
  3564.   //|3:
  3565.   //|  mov STR:RB, TMP3
  3566.   //|  sub RC, RA                                // start > end?
  3567.   //|  jl ->fff_emptystr
  3568.   //|  lea RB, [STR:RB+RA+#STR-1]
  3569.   //|  add RC, 1
  3570.   //|4:
  3571.   //|.if X64
  3572.   //|  mov TMP3, RC
  3573.   //|.else
  3574.   //|  mov ARG3, RC
  3575.   //|.endif
  3576.   //|  mov RD, RB
  3577.   //|  jmp ->fff_newstr
  3578.   //|
  3579.   //|5:  // Negative end or overflow.
  3580.   //|  jl >6
  3581.   //|  lea RC, [RC+RB+1]                        // end = end+(len+1)
  3582.   //|  jmp <2
  3583.   //|6:  // Overflow.
  3584.   //|  mov RC, RB                                // end = len
  3585.   //|  jmp <2
  3586.   //|
  3587.   //|7:  // Negative start or underflow.
  3588.   //|  je >8
  3589.   //|  add RA, RB                                // start = start+(len+1)
  3590.   dasm_put(Dst, 5523, sizeof(GCstr)-1);
  3591. #line 2317 "vm_x86.dasc"
  3592.   //|  add RA, 1
  3593.   //|  jg <3                                // start > 0?
  3594.   //|8:  // Underflow.
  3595.   //|  mov RA, 1                                // start = 1
  3596.   //|  jmp <3
  3597.   //|
  3598.   //|->fff_emptystr:  // Range underflow.
  3599.   //|  xor RC, RC                                // Zero length. Any ptr in RB is ok.
  3600.   //|  jmp <4
  3601.   //|
  3602.   //|.macro ffstring_op, name
  3603.   //|  .ffunc_1 string_ .. name
  3604.   //|  ffgccheck
  3605.   //|  cmp dword [BASE+4], LJ_TSTR;  jne ->fff_fallback
  3606.   //|  mov L:RB, SAVE_L
  3607.   //|   lea SBUF:FCARG1, [DISPATCH+DISPATCH_GL(tmpbuf)]
  3608.   //|  mov L:RB->base, BASE
  3609.   //|  mov STR:FCARG2, [BASE]                // Caveat: FCARG2 == BASE
  3610.   //|   mov RC, SBUF:FCARG1->b
  3611.   //|   mov SBUF:FCARG1->L, L:RB
  3612.   //|   mov SBUF:FCARG1->p, RC
  3613.   //|  mov SAVE_PC, PC
  3614.   //|  call extern lj_buf_putstr_ .. name .. @8
  3615.   //|  mov FCARG1, eax
  3616.   //|  call extern lj_buf_tostr@4
  3617.   //|  jmp ->fff_resstr
  3618.   //|.endmacro
  3619.   //|
  3620.   //|ffstring_op reverse
  3621.   dasm_put(Dst, 5590, 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR);
  3622. #line 2346 "vm_x86.dasc"
  3623.   //|ffstring_op lower
  3624.   dasm_put(Dst, 5652, DISPATCH_GL(tmpbuf), Dt1(->base), DtE(->b), DtE(->L), DtE(->p), 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
  3625. #line 2347 "vm_x86.dasc"
  3626.   //|ffstring_op upper
  3627.   dasm_put(Dst, 5724, LJ_TSTR, DISPATCH_GL(tmpbuf), Dt1(->base), DtE(->b), DtE(->L), DtE(->p), 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
  3628. #line 2348 "vm_x86.dasc"
  3629.   //|
  3630.   //|//-- Bit library --------------------------------------------------------
  3631.   //|
  3632.   //|.define TOBIT_BIAS, 0x59c00000        // 2^52 + 2^51 (float, not double!).
  3633.   //|
  3634.   //|.macro .ffunc_bit, name, kind
  3635.   //|  .ffunc_1 name
  3636.   //|.if kind == 2
  3637.   //|  sseconst_tobit xmm1, RBa
  3638.   //|.endif
  3639.   //|  cmp dword [BASE+4], LJ_TISNUM
  3640.   //|.if DUALNUM
  3641.   //|  jne >1
  3642.   //|  mov RB, dword [BASE]
  3643.   //|.if kind > 0
  3644.   //|  jmp >2
  3645.   //|.else
  3646.   //|  jmp ->fff_resbit
  3647.   //|.endif
  3648.   //|1:
  3649.   //|  ja ->fff_fallback
  3650.   //|.else
  3651.   //|  jae ->fff_fallback
  3652.   //|.endif
  3653.   //|  movsd xmm0, qword [BASE]
  3654.   //|.if kind < 2
  3655.   //|  sseconst_tobit xmm1, RBa
  3656.   //|.endif
  3657.   //|  addsd xmm0, xmm1
  3658.   //|  movd RB, xmm0
  3659.   //|2:
  3660.   //|.endmacro
  3661.   //|
  3662.   //|.ffunc_bit bit_tobit, 0
  3663.   dasm_put(Dst, 5801, LJ_TSTR, DISPATCH_GL(tmpbuf), Dt1(->base), DtE(->b), DtE(->L), DtE(->p), 1+1, LJ_TISNUM);
  3664. #line 2382 "vm_x86.dasc"
  3665.   //|  jmp ->fff_resbit
  3666.   //|
  3667.   //|.macro .ffunc_bit_op, name, ins
  3668.   //|  .ffunc_bit name, 2
  3669.   //|  mov TMP2, NARGS:RD                        // Save for fallback.
  3670.   //|  lea RD, [BASE+NARGS:RD*8-16]
  3671.   //|1:
  3672.   //|  cmp RD, BASE
  3673.   //|  jbe ->fff_resbit
  3674.   //|  cmp dword [RD+4], LJ_TISNUM
  3675.   //|.if DUALNUM
  3676.   //|  jne >2
  3677.   //|  ins RB, dword [RD]
  3678.   //|  sub RD, 8
  3679.   //|  jmp <1
  3680.   //|2:
  3681.   //|  ja ->fff_fallback_bit_op
  3682.   //|.else
  3683.   //|  jae ->fff_fallback_bit_op
  3684.   //|.endif
  3685.   //|  movsd xmm0, qword [RD]
  3686.   //|  addsd xmm0, xmm1
  3687.   //|  movd RA, xmm0
  3688.   //|  ins RB, RA
  3689.   //|  sub RD, 8
  3690.   //|  jmp <1
  3691.   //|.endmacro
  3692.   //|
  3693.   //|.ffunc_bit_op bit_band, and
  3694.   dasm_put(Dst, 5878, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), 1+1, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), LJ_TISNUM);
  3695. #line 2411 "vm_x86.dasc"
  3696.   //|.ffunc_bit_op bit_bor, or
  3697.   dasm_put(Dst, 5952, LJ_TISNUM, 1+1, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
  3698.   dasm_put(Dst, 6047, LJ_TISNUM, LJ_TISNUM);
  3699. #line 2412 "vm_x86.dasc"
  3700.   //|.ffunc_bit_op bit_bxor, xor
  3701.   dasm_put(Dst, 6131, 1+1, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), LJ_TISNUM);
  3702. #line 2413 "vm_x86.dasc"
  3703.   //|
  3704.   //|.ffunc_bit bit_bswap, 1
  3705.   dasm_put(Dst, 6228, LJ_TISNUM, 1+1, LJ_TISNUM);
  3706. #line 2415 "vm_x86.dasc"
  3707.   //|  bswap RB
  3708.   //|  jmp ->fff_resbit
  3709.   //|
  3710.   //|.ffunc_bit bit_bnot, 1
  3711.   dasm_put(Dst, 6303, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), 1+1, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
  3712. #line 2419 "vm_x86.dasc"
  3713.   //|  not RB
  3714.   //|.if DUALNUM
  3715.   //|  jmp ->fff_resbit
  3716.   //|.else
  3717.   //|->fff_resbit:
  3718.   //|  cvtsi2sd xmm0, RB
  3719.   //|  jmp ->fff_resxmm0
  3720.   //|.endif
  3721.   //|
  3722.   //|->fff_fallback_bit_op:
  3723.   //|  mov NARGS:RD, TMP2                        // Restore for fallback
  3724.   //|  jmp ->fff_fallback
  3725.   //|
  3726.   //|.macro .ffunc_bit_sh, name, ins
  3727.   //|.if DUALNUM
  3728.   //|  .ffunc_bit name, 1
  3729.   //|  // Note: no inline conversion from number for 2nd argument!
  3730.   //|  cmp dword [BASE+12], LJ_TISNUM; jne ->fff_fallback
  3731.   //|  mov RA, dword [BASE+8]
  3732.   //|.else
  3733.   //|  .ffunc_nnsse name
  3734.   //|  sseconst_tobit xmm2, RBa
  3735.   //|  addsd xmm0, xmm2
  3736.   //|  addsd xmm1, xmm2
  3737.   //|  movd RB, xmm0
  3738.   //|  movd RA, xmm1
  3739.   //|.endif
  3740.   //|  ins RB, cl                                // Assumes RA is ecx.
  3741.   //|  jmp ->fff_resbit
  3742.   //|.endmacro
  3743.   //|
  3744.   //|.ffunc_bit_sh bit_lshift, shl
  3745.   dasm_put(Dst, 6379, 1+1, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
  3746. #line 2451 "vm_x86.dasc"
  3747.   //|.ffunc_bit_sh bit_rshift, shr
  3748.   dasm_put(Dst, 6453, LJ_TISNUM, 1+1, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
  3749. #line 2452 "vm_x86.dasc"
  3750.   //|.ffunc_bit_sh bit_arshift, sar
  3751.   dasm_put(Dst, 6528, LJ_TISNUM, 1+1, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
  3752. #line 2453 "vm_x86.dasc"
  3753.   //|.ffunc_bit_sh bit_rol, rol
  3754.   dasm_put(Dst, 6604, LJ_TISNUM, 1+1, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
  3755. #line 2454 "vm_x86.dasc"
  3756.   //|.ffunc_bit_sh bit_ror, ror
  3757.   dasm_put(Dst, 6680, LJ_TISNUM, 1+1, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
  3758. #line 2455 "vm_x86.dasc"
  3759.   //|
  3760.   //|//-----------------------------------------------------------------------
  3761.   //|
  3762.   //|->fff_fallback_2:
  3763.   //|  mov NARGS:RD, 1+2                        // Other args are ignored, anyway.
  3764.   //|  jmp ->fff_fallback
  3765.   //|->fff_fallback_1:
  3766.   //|  mov NARGS:RD, 1+1                        // Other args are ignored, anyway.
  3767.   //|->fff_fallback:                        // Call fast function fallback handler.
  3768.   //|  // BASE = new base, RD = nargs+1
  3769.   //|  mov L:RB, SAVE_L
  3770.   //|  mov PC, [BASE-4]                        // Fallback may overwrite PC.
  3771.   //|  mov SAVE_PC, PC                        // Redundant (but a defined value).
  3772.   //|  mov L:RB->base, BASE
  3773.   //|  lea RD, [BASE+NARGS:RD*8-8]
  3774.   //|  lea RA, [RD+8*LUA_MINSTACK]        // Ensure enough space for handler.
  3775.   //|  mov L:RB->top, RD
  3776.   //|  mov CFUNC:RD, [BASE-8]
  3777.   //|  cmp RA, L:RB->maxstack
  3778.   //|  ja >5                                // Need to grow stack.
  3779.   //|.if X64
  3780.   //|  mov CARG1d, L:RB
  3781.   //|.else
  3782.   //|  mov ARG1, L:RB
  3783.   //|.endif
  3784.   //|  call aword CFUNC:RD->f                // (lua_State *L)
  3785.   //|  mov BASE, L:RB->base
  3786.   dasm_put(Dst, 6755, LJ_TISNUM, 1+2, 1+1, Dt1(->base), 8*LUA_MINSTACK, Dt1(->top), Dt1(->maxstack), Dt8(->f));
  3787. #line 2482 "vm_x86.dasc"
  3788.   //|  // Either throws an error, or recovers and returns -1, 0 or nresults+1.
  3789.   //|  test RD, RD;  jg ->fff_res                // Returned nresults+1?
  3790.   //|1:
  3791.   //|  mov RA, L:RB->top
  3792.   //|  sub RA, BASE
  3793.   //|  shr RA, 3
  3794.   //|  test RD, RD
  3795.   //|  lea NARGS:RD, [RA+1]
  3796.   //|  mov LFUNC:RB, [BASE-8]
  3797.   //|  jne ->vm_call_tail                        // Returned -1?
  3798.   //|  ins_callt                                // Returned 0: retry fast path.
  3799.   //|
  3800.   //|// Reconstruct previous base for vmeta_call during tailcall.
  3801.   //|->vm_call_tail:
  3802.   //|  mov RA, BASE
  3803.   //|  test PC, FRAME_TYPE
  3804.   //|  jnz >3
  3805.   //|  movzx RB, PC_RA
  3806.   //|  not RBa                                // Note: ~RB = -(RB+1)
  3807.   //|  lea BASE, [BASE+RB*8]                // base = base - (RB+1)*8
  3808.   //|  jmp ->vm_call_dispatch                // Resolve again for tailcall.
  3809.   //|3:
  3810.   //|  mov RB, PC
  3811.   //|  and RB, -8
  3812.   //|  sub BASE, RB
  3813.   //|  jmp ->vm_call_dispatch                // Resolve again for tailcall.
  3814.   //|
  3815.   //|5:  // Grow stack for fallback handler.
  3816.   //|  mov FCARG2, LUA_MINSTACK
  3817.   //|  mov FCARG1, L:RB
  3818.   //|  call extern lj_state_growstack@8        // (lua_State *L, int n)
  3819.   //|  mov BASE, L:RB->base
  3820.   //|  xor RD, RD                                // Simulate a return 0.
  3821.   dasm_put(Dst, 6848, Dt1(->base), Dt1(->top), Dt7(->pc), FRAME_TYPE, LUA_MINSTACK, Dt1(->base));
  3822. #line 2515 "vm_x86.dasc"
  3823.   //|  jmp <1                                // Dumb retry (goes through ff first).
  3824.   //|
  3825.   //|->fff_gcstep:                        // Call GC step function.
  3826.   //|  // BASE = new base, RD = nargs+1
  3827.   //|  pop RBa                                // Must keep stack at same level.
  3828.   //|  mov TMPa, RBa                        // Save return address
  3829.   //|  mov L:RB, SAVE_L
  3830.   //|  mov SAVE_PC, PC                        // Redundant (but a defined value).
  3831.   //|  mov L:RB->base, BASE
  3832.   //|  lea RD, [BASE+NARGS:RD*8-8]
  3833.   //|  mov FCARG1, L:RB
  3834.   //|  mov L:RB->top, RD
  3835.   //|  call extern lj_gc_step@4                // (lua_State *L)
  3836.   //|  mov BASE, L:RB->base
  3837.   //|  mov RD, L:RB->top
  3838.   //|  sub RD, BASE
  3839.   //|  shr RD, 3
  3840.   //|  add NARGS:RD, 1
  3841.   //|  mov RBa, TMPa
  3842.   //|  push RBa                                // Restore return address.
  3843.   //|  ret
  3844.   //|
  3845.   //|//-----------------------------------------------------------------------
  3846.   //|//-- Special dispatch targets -------------------------------------------
  3847.   //|//-----------------------------------------------------------------------
  3848.   //|
  3849.   //|->vm_record:                                // Dispatch target for recording phase.
  3850.   //|.if JIT
  3851.   //|  movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
  3852.   //|  test RDL, HOOK_VMEVENT                // No recording while in vmevent.
  3853.   //|  jnz >5
  3854.   //|  // Decrement the hookcount for consistency, but always do the call.
  3855.   //|  test RDL, HOOK_ACTIVE
  3856.   //|  jnz >1
  3857.   //|  test RDL, LUA_MASKLINE|LUA_MASKCOUNT
  3858.   //|  jz >1
  3859.   //|  dec dword [DISPATCH+DISPATCH_GL(hookcount)]
  3860.   //|  jmp >1
  3861.   //|.endif
  3862.   //|
  3863.   //|->vm_rethook:                        // Dispatch target for return hooks.
  3864.   //|  movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
  3865.   dasm_put(Dst, 6961, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top), DISPATCH_GL(hookmask), HOOK_VMEVENT, HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount));
  3866. #line 2557 "vm_x86.dasc"
  3867.   //|  test RDL, HOOK_ACTIVE                // Hook already active?
  3868.   //|  jnz >5
  3869.   //|  jmp >1
  3870.   //|
  3871.   //|->vm_inshook:                        // Dispatch target for instr/line hooks.
  3872.   //|  movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
  3873.   //|  test RDL, HOOK_ACTIVE                // Hook already active?
  3874.   //|  jnz >5
  3875.   //|
  3876.   //|  test RDL, LUA_MASKLINE|LUA_MASKCOUNT
  3877.   //|  jz >5
  3878.   //|  dec dword [DISPATCH+DISPATCH_GL(hookcount)]
  3879.   //|  jz >1
  3880.   //|  test RDL, LUA_MASKLINE
  3881.   //|  jz >5
  3882.   //|1:
  3883.   //|  mov L:RB, SAVE_L
  3884.   dasm_put(Dst, 7059, DISPATCH_GL(hookmask), HOOK_ACTIVE, DISPATCH_GL(hookmask), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount), LUA_MASKLINE);
  3885. #line 2574 "vm_x86.dasc"
  3886.   //|  mov L:RB->base, BASE
  3887.   //|  mov FCARG2, PC                        // Caveat: FCARG2 == BASE
  3888.   //|  mov FCARG1, L:RB
  3889.   //|  // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
  3890.   //|  call extern lj_dispatch_ins@8        // (lua_State *L, const BCIns *pc)
  3891.   //|3:
  3892.   //|  mov BASE, L:RB->base
  3893.   //|4:
  3894.   //|  movzx RA, PC_RA
  3895.   //|5:
  3896.   //|  movzx OP, PC_OP
  3897.   //|  movzx RD, PC_RD
  3898.   //|.if X64
  3899.   //|  jmp aword [DISPATCH+OP*8+GG_DISP2STATIC]        // Re-dispatch to static ins.
  3900.   //|.else
  3901.   //|  jmp aword [DISPATCH+OP*4+GG_DISP2STATIC]        // Re-dispatch to static ins.
  3902.   //|.endif
  3903.   //|
  3904.   //|->cont_hook:                                // Continue from hook yield.
  3905.   //|  add PC, 4
  3906.   //|  mov RA, [RB-24]
  3907.   //|  mov MULTRES, RA                        // Restore MULTRES for *M ins.
  3908.   //|  jmp <4
  3909.   //|
  3910.   //|->vm_hotloop:                        // Hot loop counter underflow.
  3911.   //|.if JIT
  3912.   //|  mov LFUNC:RB, [BASE-8]                // Same as curr_topL(L).
  3913.   //|  mov RB, LFUNC:RB->pc
  3914.   //|  movzx RD, byte [RB+PC2PROTO(framesize)]
  3915.   //|  lea RD, [BASE+RD*8]
  3916.   //|  mov L:RB, SAVE_L
  3917.   //|  mov L:RB->base, BASE
  3918.   //|  mov L:RB->top, RD
  3919.   //|  mov FCARG2, PC
  3920.   //|  lea FCARG1, [DISPATCH+GG_DISP2J]
  3921.   //|  mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
  3922.   //|  mov SAVE_PC, PC
  3923.   //|  call extern lj_trace_hot@8                // (jit_State *J, const BCIns *pc)
  3924.   //|  jmp <3
  3925.   //|.endif
  3926.   //|
  3927.   //|->vm_callhook:                        // Dispatch target for call hooks.
  3928.   //|  mov SAVE_PC, PC
  3929.   //|.if JIT
  3930.   //|  jmp >1
  3931.   //|.endif
  3932.   //|
  3933.   //|->vm_hotcall:                        // Hot call counter underflow.
  3934.   //|.if JIT
  3935.   //|  mov SAVE_PC, PC
  3936.   dasm_put(Dst, 7111, Dt1(->base), Dt1(->base), GG_DISP2STATIC, Dt7(->pc), PC2PROTO(framesize), Dt1(->base), Dt1(->top), GG_DISP2J, DISPATCH_J(L));
  3937. #line 2624 "vm_x86.dasc"
  3938.   //|  or PC, 1                                // Marker for hot call.
  3939.   //|1:
  3940.   //|.endif
  3941.   //|  lea RD, [BASE+NARGS:RD*8-8]
  3942.   //|  mov L:RB, SAVE_L
  3943.   //|  mov L:RB->base, BASE
  3944.   //|  mov L:RB->top, RD
  3945.   //|  mov FCARG2, PC
  3946.   //|  mov FCARG1, L:RB
  3947.   //|  call extern lj_dispatch_call@8        // (lua_State *L, const BCIns *pc)
  3948.   //|  // ASMFunction returned in eax/rax (RDa).
  3949.   //|  mov SAVE_PC, 0                        // Invalidate for subsequent line hook.
  3950.   //|.if JIT
  3951.   //|  and PC, -2
  3952.   //|.endif
  3953.   //|  mov BASE, L:RB->base
  3954.   //|  mov RAa, RDa
  3955.   //|  mov RD, L:RB->top
  3956.   //|  sub RD, BASE
  3957.   //|  mov RBa, RAa
  3958.   //|  movzx RA, PC_RA
  3959.   //|  shr RD, 3
  3960.   //|  add NARGS:RD, 1
  3961.   //|  jmp RBa
  3962.   //|
  3963.   //|->cont_stitch:                        // Trace stitching.
  3964.   //|.if JIT
  3965.   //|  // BASE = base, RC = result, RB = mbase
  3966.   //|  mov RA, [RB-24]                        // Save previous trace number.
  3967.   //|  mov TMP1, RA
  3968.   //|  mov TMP3, DISPATCH                        // Need one more register.
  3969.   //|  mov DISPATCH, MULTRES
  3970.   //|  movzx RA, PC_RA
  3971.   //|  lea RA, [BASE+RA*8]                // Call base.
  3972.   //|  sub DISPATCH, 1
  3973.   //|  jz >2
  3974.   //|1:  // Move results down.
  3975.   //|.if X64
  3976.   //|  mov RBa, [RC]
  3977.   //|  mov [RA], RBa
  3978.   //|.else
  3979.   //|  mov RB, [RC]
  3980.   //|  mov [RA], RB
  3981.   //|  mov RB, [RC+4]
  3982.   //|  mov [RA+4], RB
  3983.   //|.endif
  3984.   //|  add RC, 8
  3985.   //|  add RA, 8
  3986.   //|  sub DISPATCH, 1
  3987.   //|  jnz <1
  3988.   //|2:
  3989.   //|  movzx RC, PC_RA
  3990.   //|  movzx RB, PC_RB
  3991.   //|  add RC, RB
  3992.   //|  lea RC, [BASE+RC*8-8]
  3993.   //|3:
  3994.   //|  cmp RC, RA
  3995.   //|  ja >9                                // More results wanted?
  3996.   //|
  3997.   //|  mov DISPATCH, TMP3
  3998.   //|  mov RB, TMP1                        // Get previous trace number.
  3999.   //|  mov RA, [DISPATCH+DISPATCH_J(trace)]
  4000.   //|  mov TRACE:RD, [RA+RB*4]
  4001.   //|  test TRACE:RD, TRACE:RD
  4002.   //|  jz ->cont_nop
  4003.   //|  movzx RD, word TRACE:RD->link
  4004.   //|  cmp RD, RB
  4005.   //|  je ->cont_nop                        // Blacklisted.
  4006.   //|  test RD, RD
  4007.   dasm_put(Dst, 7236, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top), DISPATCH_J(trace), DtD(->link));
  4008. #line 2693 "vm_x86.dasc"
  4009.   //|  jne =>BC_JLOOP                        // Jump to stitched trace.
  4010.   //|
  4011.   //|  // Stitch a new trace to the previous trace.
  4012.   //|  mov [DISPATCH+DISPATCH_J(exitno)], RB
  4013.   //|  mov L:RB, SAVE_L
  4014.   //|  mov L:RB->base, BASE
  4015.   //|  mov FCARG2, PC
  4016.   //|  lea FCARG1, [DISPATCH+GG_DISP2J]
  4017.   //|  mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
  4018.   //|  call extern lj_dispatch_stitch@8        // (jit_State *J, const BCIns *pc)
  4019.   //|  mov BASE, L:RB->base
  4020.   //|  jmp ->cont_nop
  4021.   //|
  4022.   //|9:  // Fill up results with nil.
  4023.   //|  mov dword [RA+4], LJ_TNIL
  4024.   //|  add RA, 8
  4025.   //|  jmp <3
  4026.   //|.endif
  4027.   //|
  4028.   //|->vm_profhook:                        // Dispatch target for profiler hook.
  4029.   dasm_put(Dst, 7426, BC_JLOOP, DISPATCH_J(exitno), Dt1(->base), GG_DISP2J, DISPATCH_J(L), Dt1(->base), LJ_TNIL);
  4030. #line 2713 "vm_x86.dasc"
  4031. #if LJ_HASPROFILE
  4032.   //|  mov L:RB, SAVE_L
  4033.   //|  mov L:RB->base, BASE
  4034.   //|  mov FCARG2, PC                        // Caveat: FCARG2 == BASE
  4035.   //|  mov FCARG1, L:RB
  4036.   //|  call extern lj_dispatch_profile@8        // (lua_State *L, const BCIns *pc)
  4037.   //|  mov BASE, L:RB->base
  4038.   //|  // HOOK_PROFILE is off again, so re-dispatch to dynamic instruction.
  4039.   //|  sub PC, 4
  4040.   //|  jmp ->cont_nop
  4041.   dasm_put(Dst, 7479, Dt1(->base), Dt1(->base));
  4042. #line 2723 "vm_x86.dasc"
  4043. #endif
  4044.   //|
  4045.   //|//-----------------------------------------------------------------------
  4046.   //|//-- Trace exit handler -------------------------------------------------
  4047.   //|//-----------------------------------------------------------------------
  4048.   //|
  4049.   //|// Called from an exit stub with the exit number on the stack.
  4050.   //|// The 16 bit exit number is stored with two (sign-extended) push imm8.
  4051.   //|->vm_exit_handler:
  4052.   //|.if JIT
  4053.   //|.if X64
  4054.   //|  push r13; push r12
  4055.   //|  push r11; push r10; push r9; push r8
  4056.   //|  push rdi; push rsi; push rbp; lea rbp, [rsp+88]; push rbp
  4057.   //|  push rbx; push rdx; push rcx; push rax
  4058.   //|  movzx RC, byte [rbp-8]                // Reconstruct exit number.
  4059.   //|  mov RCH, byte [rbp-16]
  4060.   //|  mov [rbp-8], r15; mov [rbp-16], r14
  4061.   //|.else
  4062.   //|  push ebp; lea ebp, [esp+12]; push ebp
  4063.   //|  push ebx; push edx; push ecx; push eax
  4064.   //|  movzx RC, byte [ebp-4]                // Reconstruct exit number.
  4065.   //|  mov RCH, byte [ebp-8]
  4066.   //|  mov [ebp-4], edi; mov [ebp-8], esi
  4067.   //|.endif
  4068.   //|  // Caveat: DISPATCH is ebx.
  4069.   //|  mov DISPATCH, [ebp]
  4070.   //|  mov RA, [DISPATCH+DISPATCH_GL(vmstate)]        // Get trace number.
  4071.   //|  set_vmstate EXIT
  4072.   //|  mov [DISPATCH+DISPATCH_J(exitno)], RC
  4073.   //|  mov [DISPATCH+DISPATCH_J(parent)], RA
  4074.   //|.if X64
  4075.   //|.if X64WIN
  4076.   //|  sub rsp, 16*8+4*8                        // Room for SSE regs + save area.
  4077.   //|.else
  4078.   //|  sub rsp, 16*8                        // Room for SSE regs.
  4079.   //|.endif
  4080.   //|  add rbp, -128
  4081.   //|  movsd qword [rbp-8],   xmm15; movsd qword [rbp-16],  xmm14
  4082.   //|  movsd qword [rbp-24],  xmm13; movsd qword [rbp-32],  xmm12
  4083.   //|  movsd qword [rbp-40],  xmm11; movsd qword [rbp-48],  xmm10
  4084.   //|  movsd qword [rbp-56],  xmm9;  movsd qword [rbp-64],  xmm8
  4085.   //|  movsd qword [rbp-72],  xmm7;  movsd qword [rbp-80],  xmm6
  4086.   //|  movsd qword [rbp-88],  xmm5;  movsd qword [rbp-96],  xmm4
  4087.   //|  movsd qword [rbp-104], xmm3;  movsd qword [rbp-112], xmm2
  4088.   //|  movsd qword [rbp-120], xmm1;  movsd qword [rbp-128], xmm0
  4089.   //|.else
  4090.   //|  sub esp, 8*8+16                        // Room for SSE regs + args.
  4091.   //|  movsd qword [ebp-40], xmm7; movsd qword [ebp-48], xmm6
  4092.   //|  movsd qword [ebp-56], xmm5; movsd qword [ebp-64], xmm4
  4093.   //|  movsd qword [ebp-72], xmm3; movsd qword [ebp-80], xmm2
  4094.   //|  movsd qword [ebp-88], xmm1; movsd qword [ebp-96], xmm0
  4095.   //|.endif
  4096.   //|  // Caveat: RB is ebp.
  4097.   //|  mov L:RB, [DISPATCH+DISPATCH_GL(cur_L)]
  4098.   //|  mov BASE, [DISPATCH+DISPATCH_GL(jit_base)]
  4099.   //|  mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
  4100.   //|  mov L:RB->base, BASE
  4101.   //|.if X64WIN
  4102.   //|  lea CARG2, [rsp+4*8]
  4103.   //|.elif X64
  4104.   //|  mov CARG2, rsp
  4105.   //|.else
  4106.   //|  lea FCARG2, [esp+16]
  4107.   //|.endif
  4108.   //|  lea FCARG1, [DISPATCH+GG_DISP2J]
  4109.   //|  mov dword [DISPATCH+DISPATCH_GL(jit_base)], 0
  4110.   //|  call extern lj_trace_exit@8        // (jit_State *J, ExitState *ex)
  4111.   //|  // MULTRES or negated error code returned in eax (RD).
  4112.   //|  mov RAa, L:RB->cframe
  4113.   //|  and RAa, CFRAME_RAWMASK
  4114.   //|.if X64WIN
  4115.   //|  // Reposition stack later.
  4116.   //|.elif X64
  4117.   //|  mov rsp, RAa                        // Reposition stack to C frame.
  4118.   //|.else
  4119.   //|  mov esp, RAa                        // Reposition stack to C frame.
  4120.   //|.endif
  4121.   //|  mov [RAa+CFRAME_OFS_L], L:RB        // Set SAVE_L (on-trace resume/yield).
  4122.   //|  mov BASE, L:RB->base
  4123.   //|  mov PC, [RAa+CFRAME_OFS_PC]        // Get SAVE_PC.
  4124.   //|.if X64
  4125.   //|  jmp >1
  4126.   //|.endif
  4127.   //|.endif
  4128.   //|->vm_exit_interp:
  4129.   //|  // RD = MULTRES or negated error code, BASE, PC and DISPATCH set.
  4130.   //|.if JIT
  4131.   //|.if X64
  4132.   //|  // Restore additional callee-save registers only used in compiled code.
  4133.   //|.if X64WIN
  4134.   //|  lea RAa, [rsp+9*16+4*8]
  4135.   //|1:
  4136.   //|  movdqa xmm15, [RAa-9*16]
  4137.   //|  movdqa xmm14, [RAa-8*16]
  4138.   //|  movdqa xmm13, [RAa-7*16]
  4139.   //|  movdqa xmm12, [RAa-6*16]
  4140.   //|  movdqa xmm11, [RAa-5*16]
  4141.   //|  movdqa xmm10, [RAa-4*16]
  4142.   //|  movdqa xmm9, [RAa-3*16]
  4143.   //|  movdqa xmm8, [RAa-2*16]
  4144.   //|  movdqa xmm7, [RAa-1*16]
  4145.   //|  mov rsp, RAa                        // Reposition stack to C frame.
  4146.   //|  movdqa xmm6, [RAa]
  4147.   //|  mov r15, CSAVE_3
  4148.   //|  mov r14, CSAVE_4
  4149.   //|.else
  4150.   //|  add rsp, 16                        // Reposition stack to C frame.
  4151.   dasm_put(Dst, 7507, DISPATCH_GL(vmstate), DISPATCH_GL(vmstate), ~LJ_VMST_EXIT, DISPATCH_J(exitno), DISPATCH_J(parent), 16*8, DISPATCH_GL(cur_L), DISPATCH_GL(jit_base), DISPATCH_J(L), Dt1(->base), GG_DISP2J, DISPATCH_GL(jit_base), Dt1(->cframe), CFRAME_RAWMASK, CFRAME_OFS_L, Dt1(->base), CFRAME_OFS_PC);
  4152. #line 2831 "vm_x86.dasc"
  4153.   //|1:
  4154.   //|.endif
  4155.   //|  mov r13, TMPa
  4156.   //|  mov r12, TMPQ
  4157.   //|.endif
  4158.   dasm_put(Dst, 7750);
  4159. #line 2836 "vm_x86.dasc"
  4160. #ifdef LUA_USE_TRACE_LOGS
  4161.   //|.if X64
  4162.   //|  mov FCARG1, SAVE_L
  4163.   //|  mov L:FCARG1->base, BASE
  4164.   //|  mov RB, RD     // Save RD
  4165.   //|  mov TMP1, PC  // Save PC
  4166.   //|  mov CARG3d, PC   // CARG3d == BASE
  4167.   //|  mov FCARG2, dword [DISPATCH+DISPATCH_GL(vmstate)]
  4168.   //|  call extern lj_log_trace_direct_exit@8
  4169.   //|  mov PC, TMP1
  4170.   //|  mov RD, RB
  4171.   //|  mov RB, SAVE_L
  4172.   //|  mov BASE, L:RB->base
  4173.   //|.endif
  4174.   dasm_put(Dst, 7766, Dt1(->base), DISPATCH_GL(vmstate), Dt1(->base));
  4175. #line 2850 "vm_x86.dasc"
  4176. #endif
  4177.   //|  test RD, RD; js >9                        // Check for error from exit.
  4178.   //|  mov L:RB, SAVE_L
  4179.   //|  mov MULTRES, RD
  4180.   //|  mov LFUNC:KBASE, [BASE-8]
  4181.   //|  mov KBASE, LFUNC:KBASE->pc
  4182.   //|  mov KBASE, [KBASE+PC2PROTO(k)]
  4183.   //|  mov L:RB->base, BASE
  4184.   //|  mov dword [DISPATCH+DISPATCH_GL(jit_base)], 0
  4185.   //|  set_vmstate INTERP
  4186.   //|  // Modified copy of ins_next which handles function header dispatch, too.
  4187.   //|  mov RC, [PC]
  4188.   //|  movzx RA, RCH
  4189.   //|  movzx OP, RCL
  4190.   //|  add PC, 4
  4191.   //|  shr RC, 16
  4192.   //|  cmp OP, BC_FUNCF                        // Function header?
  4193.   //|  jb >3
  4194.   //|  cmp OP, BC_FUNCC+2                        // Fast function?
  4195.   //|  jae >4
  4196.   //|2:
  4197.   //|  mov RC, MULTRES                        // RC/RD holds nres+1.
  4198.   //|3:
  4199.   //|.if X64
  4200.   //|  jmp aword [DISPATCH+OP*8]
  4201.   //|.else
  4202.   //|  jmp aword [DISPATCH+OP*4]
  4203.   //|.endif
  4204.   //|
  4205.   //|4:  // Check frame below fast function.
  4206.   //|  mov RC, [BASE-4]
  4207.   //|  test RC, FRAME_TYPE
  4208.   //|  jnz <2                                // Trace stitching continuation?
  4209.   //|  // Otherwise set KBASE for Lua function below fast function.
  4210.   //|  movzx RC, byte [RC-3]
  4211.   dasm_put(Dst, 7801, Dt7(->pc), PC2PROTO(k), Dt1(->base), DISPATCH_GL(jit_base), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, BC_FUNCF, BC_FUNCC+2, FRAME_TYPE);
  4212. #line 2885 "vm_x86.dasc"
  4213.   //|  not RCa
  4214.   //|  mov LFUNC:KBASE, [BASE+RC*8-8]
  4215.   //|  mov KBASE, LFUNC:KBASE->pc
  4216.   //|  mov KBASE, [KBASE+PC2PROTO(k)]
  4217.   //|  jmp <2
  4218.   //|
  4219.   //|9:  // Rethrow error from the right C frame.
  4220.   //|  neg RD
  4221.   //|  mov FCARG1, L:RB
  4222.   //|  mov FCARG2, RD
  4223.   //|  call extern lj_err_throw@8                // (lua_State *L, int errcode)
  4224.   //|.endif
  4225.   //|
  4226.   //|//-----------------------------------------------------------------------
  4227.   //|//-- Math helper functions ----------------------------------------------
  4228.   //|//-----------------------------------------------------------------------
  4229.   //|
  4230.   //|// FP value rounding. Called by math.floor/math.ceil fast functions
  4231.   //|// and from JIT code. arg/ret is xmm0. xmm0-xmm3 and RD (eax) modified.
  4232.   //|.macro vm_round, name, mode, cond
  4233.   //|->name:
  4234.   //|.if not X64 and cond
  4235.   //|  movsd xmm0, qword [esp+4]
  4236.   //|  call ->name .. _sse
  4237.   //|  movsd qword [esp+4], xmm0  // Overwrite callee-owned arg.
  4238.   //|  fld qword [esp+4]
  4239.   //|  ret
  4240.   //|.endif
  4241.   //|
  4242.   //|->name .. _sse:
  4243.   //|  sseconst_abs xmm2, RDa
  4244.   //|  sseconst_2p52 xmm3, RDa
  4245.   //|  movaps xmm1, xmm0
  4246.   //|  andpd xmm1, xmm2                        // |x|
  4247.   //|  ucomisd xmm3, xmm1                        // No truncation if 2^52 <= |x|.
  4248.   //|  jbe >1
  4249.   //|  andnpd xmm2, xmm0                        // Isolate sign bit.
  4250.   //|.if mode == 2                // trunc(x)?
  4251.   //|  movaps xmm0, xmm1
  4252.   //|  addsd xmm1, xmm3                        // (|x| + 2^52) - 2^52
  4253.   //|  subsd xmm1, xmm3
  4254.   //|  sseconst_1 xmm3, RDa
  4255.   //|  cmpsd xmm0, xmm1, 1                // |x| < result?
  4256.   //|  andpd xmm0, xmm3
  4257.   //|  subsd xmm1, xmm0                        // If yes, subtract -1.
  4258.   //|  orpd xmm1, xmm2                        // Merge sign bit back in.
  4259.   //|.else
  4260.   //|  addsd xmm1, xmm3                        // (|x| + 2^52) - 2^52
  4261.   //|  subsd xmm1, xmm3
  4262.   //|  orpd xmm1, xmm2                        // Merge sign bit back in.
  4263.   //|  .if mode == 1                // ceil(x)?
  4264.   //|    sseconst_m1 xmm2, RDa                // Must subtract -1 to preserve -0.
  4265.   //|    cmpsd xmm0, xmm1, 6                // x > result?
  4266.   //|  .else                        // floor(x)?
  4267.   //|    sseconst_1 xmm2, RDa
  4268.   //|    cmpsd xmm0, xmm1, 1                // x < result?
  4269.   //|  .endif
  4270.   //|  andpd xmm0, xmm2
  4271.   //|  subsd xmm1, xmm0                        // If yes, subtract +-1.
  4272.   //|.endif
  4273.   //|  movaps xmm0, xmm1
  4274.   //|1:
  4275.   //|  ret
  4276.   //|.endmacro
  4277.   //|
  4278.   //|  vm_round vm_floor, 0, 1
  4279.   //|  vm_round vm_ceil,  1, JIT
  4280.   dasm_put(Dst, 7901, Dt7(->pc), PC2PROTO(k), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32));
  4281. #line 2952 "vm_x86.dasc"
  4282.   //|  vm_round vm_trunc, 2, JIT
  4283.   //|
  4284.   //|// FP modulo x%y. Called by BC_MOD* and vm_arith.
  4285.   //|->vm_mod:
  4286.   //|// Args in xmm0/xmm1, return value in xmm0.
  4287.   //|// Caveat: xmm0-xmm5 and RC (eax) modified!
  4288.   //|  movaps xmm5, xmm0
  4289.   //|  divsd xmm0, xmm1
  4290.   //|  sseconst_abs xmm2, RDa
  4291.   dasm_put(Dst, 8036, (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(bff00000,00000000)), (unsigned int)((U64x(bff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32));
  4292. #line 2961 "vm_x86.dasc"
  4293.   //|  sseconst_2p52 xmm3, RDa
  4294.   //|  movaps xmm4, xmm0
  4295.   //|  andpd xmm4, xmm2                        // |x/y|
  4296.   //|  ucomisd xmm3, xmm4                        // No truncation if 2^52 <= |x/y|.
  4297.   //|  jbe >1
  4298.   //|  andnpd xmm2, xmm0                        // Isolate sign bit.
  4299.   //|  addsd xmm4, xmm3                        // (|x/y| + 2^52) - 2^52
  4300.   //|  subsd xmm4, xmm3
  4301.   //|  orpd xmm4, xmm2                        // Merge sign bit back in.
  4302.   //|  sseconst_1 xmm2, RDa
  4303.   //|  cmpsd xmm0, xmm4, 1                // x/y < result?
  4304.   //|  andpd xmm0, xmm2
  4305.   //|  subsd xmm4, xmm0                        // If yes, subtract 1.0.
  4306.   //|  movaps xmm0, xmm5
  4307.   //|  mulsd xmm1, xmm4
  4308.   //|  subsd xmm0, xmm1
  4309.   //|  ret
  4310.   //|1:
  4311.   //|  mulsd xmm1, xmm0
  4312.   //|  movaps xmm0, xmm5
  4313.   //|  subsd xmm0, xmm1
  4314.   //|  ret
  4315.   //|
  4316.   //|// Args in xmm0/eax. Ret in xmm0. xmm0-xmm1 and eax modified.
  4317.   //|->vm_powi_sse:
  4318.   //|  cmp eax, 1; jle >6                        // i<=1?
  4319.   //|  // Now 1 < (unsigned)i <= 0x80000000.
  4320.   //|1:  // Handle leading zeros.
  4321.   //|  test eax, 1; jnz >2
  4322.   //|  mulsd xmm0, xmm0
  4323.   //|  shr eax, 1
  4324.   //|  jmp <1
  4325.   //|2:
  4326.   //|  shr eax, 1; jz >5
  4327.   //|  movaps xmm1, xmm0
  4328.   //|3:  // Handle trailing bits.
  4329.   //|  mulsd xmm0, xmm0
  4330.   //|  shr eax, 1; jz >4
  4331.   //|  jnc <3
  4332.   dasm_put(Dst, 8216, (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
  4333. #line 3000 "vm_x86.dasc"
  4334.   //|  mulsd xmm1, xmm0
  4335.   //|  jmp <3
  4336.   //|4:
  4337.   //|  mulsd xmm0, xmm1
  4338.   //|5:
  4339.   //|  ret
  4340.   //|6:
  4341.   //|  je <5                                // x^1 ==> x
  4342.   //|  jb >7                                // x^0 ==> 1
  4343.   //|  neg eax
  4344.   //|  call <1
  4345.   //|  sseconst_1 xmm1, RDa
  4346.   //|  divsd xmm1, xmm0
  4347.   //|  movaps xmm0, xmm1
  4348.   //|  ret
  4349.   //|7:
  4350.   //|  sseconst_1 xmm0, RDa
  4351.   //|  ret
  4352.   //|
  4353.   //|//-----------------------------------------------------------------------
  4354.   //|//-- Miscellaneous functions --------------------------------------------
  4355.   //|//-----------------------------------------------------------------------
  4356.   //|
  4357.   //|// int lj_vm_cpuid(uint32_t f, uint32_t res[4])
  4358.   //|->vm_cpuid:
  4359.   //|.if X64
  4360.   //|  mov eax, CARG1d
  4361.   //|  .if X64WIN; push rsi; mov rsi, CARG2; .endif
  4362.   //|  push rbx
  4363.   //|  cpuid
  4364.   //|  mov [rsi], eax
  4365.   //|  mov [rsi+4], ebx
  4366.   //|  mov [rsi+8], ecx
  4367.   //|  mov [rsi+12], edx
  4368.   //|  pop rbx
  4369.   //|  .if X64WIN; pop rsi; .endif
  4370.   //|  ret
  4371.   //|.else
  4372.   //|  pushfd
  4373.   //|  pop edx
  4374.   //|  mov ecx, edx
  4375.   //|  xor edx, 0x00200000                // Toggle ID bit in flags.
  4376.   //|  push edx
  4377.   //|  popfd
  4378.   //|  pushfd
  4379.   //|  pop edx
  4380.   //|  xor eax, eax                        // Zero means no features supported.
  4381.   //|  cmp ecx, edx
  4382.   //|  jz >1                                // No ID toggle means no CPUID support.
  4383.   //|  mov eax, [esp+4]                        // Argument 1 is function number.
  4384.   //|  push edi
  4385.   //|  push ebx
  4386.   //|  cpuid
  4387.   //|  mov edi, [esp+16]                        // Argument 2 is result area.
  4388.   //|  mov [edi], eax
  4389.   //|  mov [edi+4], ebx
  4390.   //|  mov [edi+8], ecx
  4391.   //|  mov [edi+12], edx
  4392.   //|  pop ebx
  4393.   //|  pop edi
  4394.   //|1:
  4395.   //|  ret
  4396.   //|.endif
  4397.   //|
  4398.   //|//-----------------------------------------------------------------------
  4399.   //|//-- Assertions ---------------------------------------------------------
  4400.   //|//-----------------------------------------------------------------------
  4401.   //|
  4402.   //|->assert_bad_for_arg_type:
  4403.   dasm_put(Dst, 8374, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
  4404. #line 3069 "vm_x86.dasc"
  4405. #ifdef LUA_USE_ASSERT
  4406.   //|  int3
  4407.   dasm_put(Dst, 8467);
  4408. #line 3071 "vm_x86.dasc"
  4409. #endif
  4410.   //|  int3
  4411.   //|
  4412.   //|//-----------------------------------------------------------------------
  4413.   //|//-- FFI helper functions -----------------------------------------------
  4414.   //|//-----------------------------------------------------------------------
  4415.   //|
  4416.   //|// Handler for callback functions. Callback slot number in ah/al.
  4417.   //|->vm_ffi_callback:
  4418.   //|.if FFI
  4419.   //|.type CTSTATE, CTState, PC
  4420. #define DtF(_V) (int)(ptrdiff_t)&(((CTState *)0)_V)
  4421. #line 3082 "vm_x86.dasc"
  4422.   //|.if not X64
  4423.   //|  sub esp, 16                        // Leave room for SAVE_ERRF etc.
  4424.   //|.endif
  4425.   //|  saveregs_        // ebp/rbp already saved. ebp now holds global_State *.
  4426.   //|  lea DISPATCH, [ebp+GG_G2DISP]
  4427.   //|  mov CTSTATE, GL:ebp->ctype_state
  4428.   //|  movzx eax, ax
  4429.   //|  mov CTSTATE->cb.slot, eax
  4430.   //|.if X64
  4431.   //|  mov CTSTATE->cb.gpr[0], CARG1
  4432.   //|  mov CTSTATE->cb.gpr[1], CARG2
  4433.   //|  mov CTSTATE->cb.gpr[2], CARG3
  4434.   //|  mov CTSTATE->cb.gpr[3], CARG4
  4435.   //|  movsd qword CTSTATE->cb.fpr[0], xmm0
  4436.   //|  movsd qword CTSTATE->cb.fpr[1], xmm1
  4437.   //|  movsd qword CTSTATE->cb.fpr[2], xmm2
  4438.   //|  movsd qword CTSTATE->cb.fpr[3], xmm3
  4439.   //|.if X64WIN
  4440.   //|  lea rax, [rsp+CFRAME_SIZE+4*8]
  4441.   //|.else
  4442.   //|  lea rax, [rsp+CFRAME_SIZE]
  4443.   //|  mov CTSTATE->cb.gpr[4], CARG5
  4444.   //|  mov CTSTATE->cb.gpr[5], CARG6
  4445.   //|  movsd qword CTSTATE->cb.fpr[4], xmm4
  4446.   //|  movsd qword CTSTATE->cb.fpr[5], xmm5
  4447.   //|  movsd qword CTSTATE->cb.fpr[6], xmm6
  4448.   //|  movsd qword CTSTATE->cb.fpr[7], xmm7
  4449.   //|.endif
  4450.   //|  mov CTSTATE->cb.stack, rax
  4451.   //|  mov CARG2, rsp
  4452.   dasm_put(Dst, 8469, GG_G2DISP, Dt2(->ctype_state), DtF(->cb.slot), DtF(->cb.gpr[0]), DtF(->cb.gpr[1]), DtF(->cb.gpr[2]), DtF(->cb.gpr[3]), DtF(->cb.fpr[0]), DtF(->cb.fpr[1]), DtF(->cb.fpr[2]), DtF(->cb.fpr[3]), CFRAME_SIZE, DtF(->cb.gpr[4]), DtF(->cb.gpr[5]), DtF(->cb.fpr[4]), DtF(->cb.fpr[5]), DtF(->cb.fpr[6]), DtF(->cb.fpr[7]), DtF(->cb.stack));
  4453. #line 3112 "vm_x86.dasc"
  4454.   //|.else
  4455.   //|  lea eax, [esp+CFRAME_SIZE+16]
  4456.   //|  mov CTSTATE->cb.gpr[0], FCARG1
  4457.   //|  mov CTSTATE->cb.gpr[1], FCARG2
  4458.   //|  mov CTSTATE->cb.stack, eax
  4459.   //|  mov FCARG1, [esp+CFRAME_SIZE+12]        // Move around misplaced retaddr/ebp.
  4460.   //|  mov FCARG2, [esp+CFRAME_SIZE+8]
  4461.   //|  mov SAVE_RET, FCARG1
  4462.   //|  mov SAVE_R4, FCARG2
  4463.   //|  mov FCARG2, esp
  4464.   //|.endif
  4465.   //|  mov SAVE_PC, CTSTATE                // Any value outside of bytecode is ok.
  4466.   //|  mov FCARG1, CTSTATE
  4467.   //|  call extern lj_ccallback_enter@8        // (CTState *cts, void *cf)
  4468.   //|  // lua_State * returned in eax (RD).
  4469.   //|  set_vmstate INTERP
  4470.   //|  mov BASE, L:RD->base
  4471.   //|  mov RD, L:RD->top
  4472.   //|  sub RD, BASE
  4473.   //|  mov LFUNC:RB, [BASE-8]
  4474.   //|  shr RD, 3
  4475.   //|  add RD, 1
  4476.   //|  ins_callt
  4477.   //|.endif
  4478.   //|
  4479.   //|->cont_ffi_callback:                        // Return from FFI callback.
  4480.   //|.if FFI
  4481.   //|  mov L:RA, SAVE_L
  4482.   //|  mov CTSTATE, [DISPATCH+DISPATCH_GL(ctype_state)]
  4483.   //|  mov aword CTSTATE->L, L:RAa
  4484.   //|  mov L:RA->base, BASE
  4485.   //|  mov L:RA->top, RB
  4486.   //|  mov FCARG1, CTSTATE
  4487.   //|  mov FCARG2, RC
  4488.   //|  call extern lj_ccallback_leave@8        // (CTState *cts, TValue *o)
  4489.   //|.if X64
  4490.   //|  mov rax, CTSTATE->cb.gpr[0]
  4491.   //|  movsd xmm0, qword CTSTATE->cb.fpr[0]
  4492.   //|  jmp ->vm_leave_unw
  4493.   //|.else
  4494.   //|  mov L:RB, SAVE_L
  4495.   //|  mov eax, CTSTATE->cb.gpr[0]
  4496.   //|  mov edx, CTSTATE->cb.gpr[1]
  4497.   //|  cmp dword CTSTATE->cb.gpr[2], 1
  4498.   //|  jb >7
  4499.   //|  je >6
  4500.   //|  fld qword CTSTATE->cb.fpr[0].d
  4501.   //|  jmp >7
  4502.   //|6:
  4503.   //|  fld dword CTSTATE->cb.fpr[0].f
  4504.   //|7:
  4505.   //|  mov ecx, L:RB->top
  4506.   //|  movzx ecx, word [ecx+6]                // Get stack adjustment and copy up.
  4507.   //|  mov SAVE_L, ecx                        // Must be one slot above SAVE_RET
  4508.   //|  restoreregs
  4509.   //|  pop ecx                                // Move return addr from SAVE_RET.
  4510.   //|  add esp, [esp]                        // Adjust stack.
  4511.   //|  add esp, 16
  4512.   //|  push ecx
  4513.   //|  ret
  4514.   //|.endif
  4515.   //|.endif
  4516.   //|
  4517.   //|->vm_ffi_call@4:                        // Call C function via FFI.
  4518.   //|  // Caveat: needs special frame unwinding, see below.
  4519.   //|.if FFI
  4520.   //|.if X64
  4521.   //|  .type CCSTATE, CCallState, rbx
  4522. #define Dt10(_V) (int)(ptrdiff_t)&(((CCallState *)0)_V)
  4523. #line 3180 "vm_x86.dasc"
  4524.   //|  push rbp; mov rbp, rsp; push rbx; mov CCSTATE, CARG1
  4525.   //|.else
  4526.   //|  .type CCSTATE, CCallState, ebx
  4527.   //|  push ebp; mov ebp, esp; push ebx; mov CCSTATE, FCARG1
  4528.   //|.endif
  4529.   //|
  4530.   //|  // Readjust stack.
  4531.   //|.if X64
  4532.   //|  mov eax, CCSTATE->spadj
  4533.   //|  sub rsp, rax
  4534.   //|.else
  4535.   //|  sub esp, CCSTATE->spadj
  4536.   //|.if WIN
  4537.   //|  mov CCSTATE->spadj, esp
  4538.   //|.endif
  4539.   //|.endif
  4540.   //|
  4541.   //|  // Copy stack slots.
  4542.   //|  movzx ecx, byte CCSTATE->nsp
  4543.   //|  sub ecx, 1
  4544.   //|  js >2
  4545.   //|1:
  4546.   //|.if X64
  4547.   //|  mov rax, [CCSTATE+rcx*8+offsetof(CCallState, stack)]
  4548.   dasm_put(Dst, 8578, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top), Dt7(->pc), DISPATCH_GL(ctype_state), DtF(->L), Dt1(->base), Dt1(->top), DtF(->cb.gpr[0]), DtF(->cb.fpr[0]), Dt10(->spadj), Dt10(->nsp));
  4549. #line 3204 "vm_x86.dasc"
  4550.   //|  mov [rsp+rcx*8+CCALL_SPS_EXTRA*8], rax
  4551.   //|.else
  4552.   //|  mov eax, [CCSTATE+ecx*4+offsetof(CCallState, stack)]
  4553.   //|  mov [esp+ecx*4], eax
  4554.   //|.endif
  4555.   //|  sub ecx, 1
  4556.   //|  jns <1
  4557.   //|2:
  4558.   //|
  4559.   //|.if X64
  4560.   //|  movzx eax, byte CCSTATE->nfpr
  4561.   //|  mov CARG1, CCSTATE->gpr[0]
  4562.   //|  mov CARG2, CCSTATE->gpr[1]
  4563.   //|  mov CARG3, CCSTATE->gpr[2]
  4564.   //|  mov CARG4, CCSTATE->gpr[3]
  4565.   //|.if not X64WIN
  4566.   //|  mov CARG5, CCSTATE->gpr[4]
  4567.   //|  mov CARG6, CCSTATE->gpr[5]
  4568.   //|.endif
  4569.   //|  test eax, eax; jz >5
  4570.   //|  movaps xmm0, CCSTATE->fpr[0]
  4571.   //|  movaps xmm1, CCSTATE->fpr[1]
  4572.   //|  movaps xmm2, CCSTATE->fpr[2]
  4573.   //|  movaps xmm3, CCSTATE->fpr[3]
  4574.   //|.if not X64WIN
  4575.   //|  cmp eax, 4; jbe >5
  4576.   //|  movaps xmm4, CCSTATE->fpr[4]
  4577.   dasm_put(Dst, 8709, offsetof(CCallState, stack), CCALL_SPS_EXTRA*8, Dt10(->nfpr), Dt10(->gpr[0]), Dt10(->gpr[1]), Dt10(->gpr[2]), Dt10(->gpr[3]), Dt10(->gpr[4]), Dt10(->gpr[5]), Dt10(->fpr[0]), Dt10(->fpr[1]), Dt10(->fpr[2]), Dt10(->fpr[3]));
  4578. #line 3231 "vm_x86.dasc"
  4579.   //|  movaps xmm5, CCSTATE->fpr[5]
  4580.   //|  movaps xmm6, CCSTATE->fpr[6]
  4581.   //|  movaps xmm7, CCSTATE->fpr[7]
  4582.   //|.endif
  4583.   //|5:
  4584.   //|.else
  4585.   //|  mov FCARG1, CCSTATE->gpr[0]
  4586.   //|  mov FCARG2, CCSTATE->gpr[1]
  4587.   //|.endif
  4588.   //|
  4589.   //|  call aword CCSTATE->func
  4590.   //|
  4591.   //|.if X64
  4592.   //|  mov CCSTATE->gpr[0], rax
  4593.   //|  movaps CCSTATE->fpr[0], xmm0
  4594.   //|.if not X64WIN
  4595.   //|  mov CCSTATE->gpr[1], rdx
  4596.   //|  movaps CCSTATE->fpr[1], xmm1
  4597.   //|.endif
  4598.   //|.else
  4599.   //|  mov CCSTATE->gpr[0], eax
  4600.   //|  mov CCSTATE->gpr[1], edx
  4601.   //|  cmp byte CCSTATE->resx87, 1
  4602.   //|  jb >7
  4603.   //|  je >6
  4604.   //|  fstp qword CCSTATE->fpr[0].d[0]
  4605.   //|  jmp >7
  4606.   //|6:
  4607.   //|  fstp dword CCSTATE->fpr[0].f[0]
  4608.   //|7:
  4609.   //|.if WIN
  4610.   //|  sub CCSTATE->spadj, esp
  4611.   //|.endif
  4612.   //|.endif
  4613.   //|
  4614.   //|.if X64
  4615.   //|  mov rbx, [rbp-8]; leave; ret
  4616.   //|.else
  4617.   //|  mov ebx, [ebp-4]; leave; ret
  4618.   //|.endif
  4619.   //|.endif
  4620.   //|// Note: vm_ffi_call must be the last function in this object file!
  4621.   //|
  4622.   //|//-----------------------------------------------------------------------
  4623.   dasm_put(Dst, 8790, Dt10(->fpr[4]), Dt10(->fpr[5]), Dt10(->fpr[6]), Dt10(->fpr[7]), Dt10(->func), Dt10(->gpr[0]), Dt10(->fpr[0]), Dt10(->gpr[1]), Dt10(->fpr[1]));
  4624. #line 3275 "vm_x86.dasc"
  4625. }

  4626. /* Generate the code for a single instruction. */
  4627. static void build_ins(BuildCtx *ctx, BCOp op, int defop)
  4628. {
  4629.   int vk = 0;
  4630.   //|// Note: aligning all instructions does not pay off.
  4631.   //|=>defop:
  4632.   dasm_put(Dst, 8836, defop);
  4633. #line 3283 "vm_x86.dasc"

  4634.   switch (op) {

  4635.   /* -- Comparison ops ---------------------------------------------------- */

  4636.   /* Remember: all ops branch for a true comparison, fall through otherwise. */

  4637.   //|.macro jmp_comp, lt, ge, le, gt, target
  4638.   //||switch (op) {
  4639.   //||case BC_ISLT:
  4640.   //|   lt target
  4641.   //||break;
  4642.   //||case BC_ISGE:
  4643.   //|   ge target
  4644.   //||break;
  4645.   //||case BC_ISLE:
  4646.   //|   le target
  4647.   //||break;
  4648.   //||case BC_ISGT:
  4649.   //|   gt target
  4650.   //||break;
  4651.   //||default: break;  /* Shut up GCC. */
  4652.   //||}
  4653.   //|.endmacro

  4654.   case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
  4655.     //|  // RA = src1, RD = src2, JMP with RD = target
  4656.     //|  ins_AD
  4657.     //|.if DUALNUM
  4658.     //|  checkint RA, >7
  4659.     //|  checkint RD, >8
  4660.     //|  mov RB, dword [BASE+RA*8]
  4661.     //|  add PC, 4
  4662.     //|  cmp RB, dword [BASE+RD*8]
  4663.     //|  jmp_comp jge, jl, jg, jle, >9
  4664.     dasm_put(Dst, 8838, LJ_TISNUM, LJ_TISNUM);
  4665.     switch (op) {
  4666.     case BC_ISLT:
  4667.     dasm_put(Dst, 8868);
  4668.     break;
  4669.     case BC_ISGE:
  4670.     dasm_put(Dst, 8873);
  4671.     break;
  4672.     case BC_ISLE:
  4673.     dasm_put(Dst, 8878);
  4674.     break;
  4675.     case BC_ISGT:
  4676.     dasm_put(Dst, 8883);
  4677.     break;
  4678.     default: break/* Shut up GCC. */
  4679.     }
  4680. #line 3318 "vm_x86.dasc"
  4681.     //|6:
  4682.     //|  movzx RD, PC_RD
  4683.     //|  branchPC RD
  4684.     //|9:
  4685.     //|  ins_next
  4686.     //|
  4687.     //|7:  // RA is not an integer.
  4688.     //|  ja ->vmeta_comp
  4689.     //|  // RA is a number.
  4690.     //|  cmp dword [BASE+RD*8+4], LJ_TISNUM; jb >1; jne ->vmeta_comp
  4691.     //|  // RA is a number, RD is an integer.
  4692.     //|  cvtsi2sd xmm0, dword [BASE+RD*8]
  4693.     //|  jmp >2
  4694.     //|
  4695.     //|8:  // RA is an integer, RD is not an integer.
  4696.     //|  ja ->vmeta_comp
  4697.     //|  // RA is an integer, RD is a number.
  4698.     //|  cvtsi2sd xmm1, dword [BASE+RA*8]
  4699.     //|  movsd xmm0, qword [BASE+RD*8]
  4700.     //|  add PC, 4
  4701.     //|  ucomisd xmm0, xmm1
  4702.     //|  jmp_comp jbe, ja, jb, jae, <9
  4703.     dasm_put(Dst, 8888, -BCBIAS_J*4, LJ_TISNUM);
  4704.     switch (op) {
  4705.     case BC_ISLT:
  4706.     dasm_put(Dst, 8978);
  4707.     break;
  4708.     case BC_ISGE:
  4709.     dasm_put(Dst, 8983);
  4710.     break;
  4711.     case BC_ISLE:
  4712.     dasm_put(Dst, 8988);
  4713.     break;
  4714.     case BC_ISGT:
  4715.     dasm_put(Dst, 8993);
  4716.     break;
  4717.     default: break/* Shut up GCC. */
  4718.     }
  4719. #line 3340 "vm_x86.dasc"
  4720.     //|  jmp <6
  4721.     //|.else
  4722.     //|  checknum RA, ->vmeta_comp
  4723.     //|  checknum RD, ->vmeta_comp
  4724.     //|.endif
  4725.     //|1:
  4726.     //|  movsd xmm0, qword [BASE+RD*8]
  4727.     //|2:
  4728.     //|  add PC, 4
  4729.     //|  ucomisd xmm0, qword [BASE+RA*8]
  4730.     //|3:
  4731.     //|  // Unordered: all of ZF CF PF set, ordered: PF clear.
  4732.     //|  // To preserve NaN semantics GE/GT branch on unordered, but LT/LE don't.
  4733.     //|.if DUALNUM
  4734.     //|  jmp_comp jbe, ja, jb, jae, <9
  4735.     dasm_put(Dst, 8998);
  4736.     switch (op) {
  4737.     case BC_ISLT:
  4738.     dasm_put(Dst, 8978);
  4739.     break;
  4740.     case BC_ISGE:
  4741.     dasm_put(Dst, 8983);
  4742.     break;
  4743.     case BC_ISLE:
  4744.     dasm_put(Dst, 8988);
  4745.     break;
  4746.     case BC_ISGT:
  4747.     dasm_put(Dst, 8993);
  4748.     break;
  4749.     default: break/* Shut up GCC. */
  4750.     }
  4751. #line 3355 "vm_x86.dasc"
  4752.     //|  jmp <6
  4753.     //|.else
  4754.     //|  jmp_comp jbe, ja, jb, jae, >1
  4755.     //|  movzx RD, PC_RD
  4756.     //|  branchPC RD
  4757.     //|1:
  4758.     //|  ins_next
  4759.     //|.endif
  4760.     dasm_put(Dst, 9023);
  4761. #line 3363 "vm_x86.dasc"
  4762.     break;

  4763.   case BC_ISEQV: case BC_ISNEV:
  4764.     vk = op == BC_ISEQV;
  4765.     //|  ins_AD        // RA = src1, RD = src2, JMP with RD = target
  4766.     //|  mov RB, [BASE+RD*8+4]
  4767.     //|  add PC, 4
  4768.     //|.if DUALNUM
  4769.     //|  cmp RB, LJ_TISNUM; jne >7
  4770.     //|  checkint RA, >8
  4771.     //|  mov RB, dword [BASE+RD*8]
  4772.     //|  cmp RB, dword [BASE+RA*8]
  4773.     dasm_put(Dst, 9028, LJ_TISNUM, LJ_TISNUM);
  4774. #line 3375 "vm_x86.dasc"
  4775.     if (vk) {
  4776.       //|  jne >9
  4777.       dasm_put(Dst, 9060);
  4778. #line 3377 "vm_x86.dasc"
  4779.     } else {
  4780.       //|  je >9
  4781.       dasm_put(Dst, 9065);
  4782. #line 3379 "vm_x86.dasc"
  4783.     }
  4784.     //|  movzx RD, PC_RD
  4785.     //|  branchPC RD
  4786.     //|9:
  4787.     //|  ins_next
  4788.     //|
  4789.     //|7:  // RD is not an integer.
  4790.     //|  ja >5
  4791.     //|  // RD is a number.
  4792.     //|  cmp dword [BASE+RA*8+4], LJ_TISNUM; jb >1; jne >5
  4793.     //|  // RD is a number, RA is an integer.
  4794.     //|  cvtsi2sd xmm0, dword [BASE+RA*8]
  4795.     //|  jmp >2
  4796.     //|
  4797.     //|8:  // RD is an integer, RA is not an integer.
  4798.     //|  ja >5
  4799.     //|  // RD is an integer, RA is a number.
  4800.     //|  cvtsi2sd xmm0, dword [BASE+RD*8]
  4801.     //|  ucomisd xmm0, qword [BASE+RA*8]
  4802.     //|  jmp >4
  4803.     //|
  4804.     //|.else
  4805.     //|  cmp RB, LJ_TISNUM; jae >5
  4806.     //|  checknum RA, >5
  4807.     //|.endif
  4808.     //|1:
  4809.     //|  movsd xmm0, qword [BASE+RA*8]
  4810.     //|2:
  4811.     //|  ucomisd xmm0, qword [BASE+RD*8]
  4812.     //|4:
  4813.     dasm_put(Dst, 9070, -BCBIAS_J*4, LJ_TISNUM);
  4814. #line 3409 "vm_x86.dasc"
  4815.   iseqne_fp:
  4816.     if (vk) {
  4817.       //|  jp >2                                // Unordered means not equal.
  4818.       //|  jne >2
  4819.       dasm_put(Dst, 9171);
  4820. #line 3413 "vm_x86.dasc"
  4821.     } else {
  4822.       //|  jp >2                                // Unordered means not equal.
  4823.       //|  je >1
  4824.       dasm_put(Dst, 9180);
  4825. #line 3416 "vm_x86.dasc"
  4826.     }
  4827.   iseqne_end:
  4828.     if (vk) {
  4829.       //|1:                                // EQ: Branch to the target.
  4830.       //|  movzx RD, PC_RD
  4831.       //|  branchPC RD
  4832.       //|2:                                // NE: Fallthrough to next instruction.
  4833.       //|.if not FFI
  4834.       //|3:
  4835.       //|.endif
  4836.       dasm_put(Dst, 9189, -BCBIAS_J*4);
  4837. #line 3426 "vm_x86.dasc"
  4838.     } else {
  4839.       //|.if not FFI
  4840.       //|3:
  4841.       //|.endif
  4842.       //|2:                                // NE: Branch to the target.
  4843.       //|  movzx RD, PC_RD
  4844.       //|  branchPC RD
  4845.       //|1:                                // EQ: Fallthrough to next instruction.
  4846.       dasm_put(Dst, 9204, -BCBIAS_J*4);
  4847. #line 3434 "vm_x86.dasc"
  4848.     }
  4849.     if (LJ_DUALNUM && (op == BC_ISEQV || op == BC_ISNEV ||
  4850.                        op == BC_ISEQN || op == BC_ISNEN)) {
  4851.       //|  jmp <9
  4852.       dasm_put(Dst, 9219);
  4853. #line 3438 "vm_x86.dasc"
  4854.     } else {
  4855.       //|  ins_next
  4856.       dasm_put(Dst, 9224);
  4857. #line 3440 "vm_x86.dasc"
  4858.     }
  4859.     //|
  4860.     if (op == BC_ISEQV || op == BC_ISNEV) {
  4861.       //|5:  // Either or both types are not numbers.
  4862.       //|.if FFI
  4863.       //|  cmp RB, LJ_TCDATA; je ->vmeta_equal_cd
  4864.       //|  checktp RA, LJ_TCDATA; je ->vmeta_equal_cd
  4865.       //|.endif
  4866.       //|  checktp RA, RB                        // Compare types.
  4867.       //|  jne <2                                // Not the same type?
  4868.       //|  cmp RB, LJ_TISPRI
  4869.       //|  jae <1                                // Same type and primitive type?
  4870.       //|
  4871.       //|  // Same types and not a primitive type. Compare GCobj or pvalue.
  4872.       //|  mov RA, [BASE+RA*8]
  4873.       //|  mov RD, [BASE+RD*8]
  4874.       //|  cmp RA, RD
  4875.       //|  je <1                                // Same GCobjs or pvalues?
  4876.       //|  cmp RB, LJ_TISTABUD
  4877.       //|  ja <2                                // Different objects and not table/ud?
  4878.       //|.if X64
  4879.       //|  cmp RB, LJ_TUDATA                // And not 64 bit lightuserdata.
  4880.       //|  jb <2
  4881.       //|.endif
  4882.       //|
  4883.       //|  // Different tables or userdatas. Need to check __eq metamethod.
  4884.       //|  // Field metatable must be at same offset for GCtab and GCudata!
  4885.       //|  mov TAB:RB, TAB:RA->metatable
  4886.       dasm_put(Dst, 9245, LJ_TCDATA, LJ_TCDATA, LJ_TISPRI, LJ_TISTABUD, LJ_TUDATA);
  4887. #line 3468 "vm_x86.dasc"
  4888.       //|  test TAB:RB, TAB:RB
  4889.       //|  jz <2                                // No metatable?
  4890.       //|  test byte TAB:RB->nomm, 1<<MM_eq
  4891.       //|  jnz <2                                // Or 'no __eq' flag set?
  4892.       dasm_put(Dst, 9310, Dt6(->metatable), Dt6(->nomm), 1<<MM_eq);
  4893. #line 3472 "vm_x86.dasc"
  4894.       if (vk) {
  4895.         //|  xor RB, RB                        // ne = 0
  4896.         dasm_put(Dst, 9330);
  4897. #line 3474 "vm_x86.dasc"
  4898.       } else {
  4899.         //|  mov RB, 1                        // ne = 1
  4900.         dasm_put(Dst, 9334);
  4901. #line 3476 "vm_x86.dasc"
  4902.       }
  4903.       //|  jmp ->vmeta_equal                // Handle __eq metamethod.
  4904.       dasm_put(Dst, 9340);
  4905. #line 3478 "vm_x86.dasc"
  4906.     } else {
  4907.       //|.if FFI
  4908.       //|3:
  4909.       //|  cmp RB, LJ_TCDATA
  4910.       dasm_put(Dst, 9345, LJ_TCDATA);
  4911. #line 3482 "vm_x86.dasc"
  4912.       if (LJ_DUALNUM && vk) {
  4913.         //|  jne <9
  4914.         dasm_put(Dst, 9352);
  4915. #line 3484 "vm_x86.dasc"
  4916.       } else {
  4917.         //|  jne <2
  4918.         dasm_put(Dst, 7896);
  4919. #line 3486 "vm_x86.dasc"
  4920.       }
  4921.       //|  jmp ->vmeta_equal_cd
  4922.       //|.endif
  4923.       dasm_put(Dst, 9357);
  4924. #line 3489 "vm_x86.dasc"
  4925.     }
  4926.     break;
  4927.   case BC_ISEQS: case BC_ISNES:
  4928.     vk = op == BC_ISEQS;
  4929.     //|  ins_AND        // RA = src, RD = str const, JMP with RD = target
  4930.     //|  mov RB, [BASE+RA*8+4]
  4931.     //|  add PC, 4
  4932.     //|  cmp RB, LJ_TSTR; jne >3
  4933.     //|  mov RA, [BASE+RA*8]
  4934.     //|  cmp RA, [KBASE+RD*4]
  4935.     dasm_put(Dst, 9362, LJ_TSTR);
  4936. #line 3499 "vm_x86.dasc"
  4937.   iseqne_test:
  4938.     if (vk) {
  4939.       //|  jne >2
  4940.       dasm_put(Dst, 3670);
  4941. #line 3502 "vm_x86.dasc"
  4942.     } else {
  4943.       //|  je >1
  4944.       dasm_put(Dst, 9184);
  4945. #line 3504 "vm_x86.dasc"
  4946.     }
  4947.     goto iseqne_end;
  4948.   case BC_ISEQN: case BC_ISNEN:
  4949.     vk = op == BC_ISEQN;
  4950.     //|  ins_AD        // RA = src, RD = num const, JMP with RD = target
  4951.     //|  mov RB, [BASE+RA*8+4]
  4952.     //|  add PC, 4
  4953.     //|.if DUALNUM
  4954.     //|  cmp RB, LJ_TISNUM; jne >7
  4955.     //|  cmp dword [KBASE+RD*8+4], LJ_TISNUM; jne >8
  4956.     //|  mov RB, dword [KBASE+RD*8]
  4957.     //|  cmp RB, dword [BASE+RA*8]
  4958.     dasm_put(Dst, 9389, LJ_TISNUM, LJ_TISNUM);
  4959. #line 3516 "vm_x86.dasc"
  4960.     if (vk) {
  4961.       //|  jne >9
  4962.       dasm_put(Dst, 9060);
  4963. #line 3518 "vm_x86.dasc"
  4964.     } else {
  4965.       //|  je >9
  4966.       dasm_put(Dst, 9065);
  4967. #line 3520 "vm_x86.dasc"
  4968.     }
  4969.     //|  movzx RD, PC_RD
  4970.     //|  branchPC RD
  4971.     //|9:
  4972.     //|  ins_next
  4973.     //|
  4974.     //|7:  // RA is not an integer.
  4975.     //|  ja >3
  4976.     //|  // RA is a number.
  4977.     //|  cmp dword [KBASE+RD*8+4], LJ_TISNUM; jb >1
  4978.     //|  // RA is a number, RD is an integer.
  4979.     //|  cvtsi2sd xmm0, dword [KBASE+RD*8]
  4980.     //|  jmp >2
  4981.     //|
  4982.     //|8:  // RA is an integer, RD is a number.
  4983.     //|  cvtsi2sd xmm0, dword [BASE+RA*8]
  4984.     //|  ucomisd xmm0, qword [KBASE+RD*8]
  4985.     //|  jmp >4
  4986.     //|.else
  4987.     //|  cmp RB, LJ_TISNUM; jae >3
  4988.     //|.endif
  4989.     //|1:
  4990.     //|  movsd xmm0, qword [KBASE+RD*8]
  4991.     //|2:
  4992.     //|  ucomisd xmm0, qword [BASE+RA*8]
  4993.     //|4:
  4994.     dasm_put(Dst, 9423, -BCBIAS_J*4, LJ_TISNUM);
  4995. #line 3546 "vm_x86.dasc"
  4996.     goto iseqne_fp;
  4997.   case BC_ISEQP: case BC_ISNEP:
  4998.     vk = op == BC_ISEQP;
  4999.     //|  ins_AND        // RA = src, RD = primitive type (~), JMP with RD = target
  5000.     //|  mov RB, [BASE+RA*8+4]
  5001.     //|  add PC, 4
  5002.     //|  cmp RB, RD
  5003.     dasm_put(Dst, 9520);
  5004. #line 3553 "vm_x86.dasc"
  5005.     if (!LJ_HASFFI) goto iseqne_test;
  5006.     if (vk) {
  5007.       //|  jne >3
  5008.       //|  movzx RD, PC_RD
  5009.       //|  branchPC RD
  5010.       //|2:
  5011.       //|  ins_next
  5012.       //|3:
  5013.       //|  cmp RB, LJ_TCDATA; jne <2
  5014.       //|  jmp ->vmeta_equal_cd
  5015.       dasm_put(Dst, 9534, -BCBIAS_J*4, LJ_TCDATA);
  5016. #line 3563 "vm_x86.dasc"
  5017.     } else {
  5018.       //|  je >2
  5019.       //|  cmp RB, LJ_TCDATA; je ->vmeta_equal_cd
  5020.       //|  movzx RD, PC_RD
  5021.       //|  branchPC RD
  5022.       //|2:
  5023.       //|  ins_next
  5024.       dasm_put(Dst, 9585, LJ_TCDATA, -BCBIAS_J*4);
  5025. #line 3570 "vm_x86.dasc"
  5026.     }
  5027.     break;

  5028.   /* -- Unary test and copy ops ------------------------------------------- */

  5029.   case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
  5030.     //|  ins_AD        // RA = dst or unused, RD = src, JMP with RD = target
  5031.     //|  mov RB, [BASE+RD*8+4]
  5032.     //|  add PC, 4
  5033.     //|  cmp RB, LJ_TISTRUECOND
  5034.     dasm_put(Dst, 9630, LJ_TISTRUECOND);
  5035. #line 3580 "vm_x86.dasc"
  5036.     if (op == BC_IST || op == BC_ISTC) {
  5037.       //|  jae >1
  5038.       dasm_put(Dst, 9642);
  5039. #line 3582 "vm_x86.dasc"
  5040.     } else {
  5041.       //|  jb >1
  5042.       dasm_put(Dst, 5428);
  5043. #line 3584 "vm_x86.dasc"
  5044.     }
  5045.     if (op == BC_ISTC || op == BC_ISFC) {
  5046.       //|  mov [BASE+RA*8+4], RB
  5047.       //|  mov RB, [BASE+RD*8]
  5048.       //|  mov [BASE+RA*8], RB
  5049.       dasm_put(Dst, 9647);
  5050. #line 3589 "vm_x86.dasc"
  5051.     }
  5052.     //|  movzx RD, PC_RD
  5053.     //|  branchPC RD
  5054.     //|1:                                        // Fallthrough to the next instruction.
  5055.     //|  ins_next
  5056.     dasm_put(Dst, 9658, -BCBIAS_J*4);
  5057. #line 3594 "vm_x86.dasc"
  5058.     break;

  5059.   case BC_ISTYPE:
  5060.     //|  ins_AD        // RA = src, RD = -type
  5061.     //|  add RD, [BASE+RA*8+4]
  5062.     //|  jne ->vmeta_istype
  5063.     //|  ins_next
  5064.     dasm_put(Dst, 9691);
  5065. #line 3601 "vm_x86.dasc"
  5066.     break;
  5067.   case BC_ISNUM:
  5068.     //|  ins_AD        // RA = src, RD = -(TISNUM-1)
  5069.     //|  checknum RA, ->vmeta_istype
  5070.     //|  ins_next
  5071.     dasm_put(Dst, 9720, LJ_TISNUM);
  5072. #line 3606 "vm_x86.dasc"
  5073.     break;

  5074.   /* -- Unary ops --------------------------------------------------------- */

  5075.   case BC_MOV:
  5076.     //|  ins_AD        // RA = dst, RD = src
  5077.     //|.if X64
  5078.     //|  mov RBa, [BASE+RD*8]
  5079.     //|  mov [BASE+RA*8], RBa
  5080.     //|.else
  5081.     //|  mov RB, [BASE+RD*8+4]
  5082.     //|  mov RD, [BASE+RD*8]
  5083.     //|  mov [BASE+RA*8+4], RB
  5084.     //|  mov [BASE+RA*8], RD
  5085.     //|.endif
  5086.     //|  ins_next_
  5087.     dasm_put(Dst, 9751);
  5088. #line 3622 "vm_x86.dasc"
  5089.     break;
  5090.   case BC_NOT:
  5091.     //|  ins_AD        // RA = dst, RD = src
  5092.     //|  xor RB, RB
  5093.     //|  checktp RD, LJ_TISTRUECOND
  5094.     //|  adc RB, LJ_TTRUE
  5095.     //|  mov [BASE+RA*8+4], RB
  5096.     //|  ins_next
  5097.     dasm_put(Dst, 9780, LJ_TISTRUECOND, LJ_TTRUE);
  5098. #line 3630 "vm_x86.dasc"
  5099.     break;
  5100.   case BC_UNM:
  5101.     //|  ins_AD        // RA = dst, RD = src
  5102.     //|.if DUALNUM
  5103.     //|  checkint RD, >5
  5104.     //|  mov RB, [BASE+RD*8]
  5105.     //|  neg RB
  5106.     //|  jo >4
  5107.     //|  mov dword [BASE+RA*8+4], LJ_TISNUM
  5108.     //|  mov dword [BASE+RA*8], RB
  5109.     //|9:
  5110.     //|  ins_next
  5111.     //|4:
  5112.     //|  mov dword [BASE+RA*8+4], 0x41e00000  // 2^31.
  5113.     //|  mov dword [BASE+RA*8], 0
  5114.     //|  jmp <9
  5115.     //|5:
  5116.     //|  ja ->vmeta_unm
  5117.     //|.else
  5118.     //|  checknum RD, ->vmeta_unm
  5119.     //|.endif
  5120.     //|  movsd xmm0, qword [BASE+RD*8]
  5121.     //|  sseconst_sign xmm1, RDa
  5122.     //|  xorps xmm0, xmm1
  5123.     //|  movsd qword [BASE+RA*8], xmm0
  5124.     //|.if DUALNUM
  5125.     //|  jmp <9
  5126.     //|.else
  5127.     //|  ins_next
  5128.     //|.endif
  5129.     dasm_put(Dst, 9817, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(80000000,00000000)), (unsigned int)((U64x(80000000,00000000))>>32));
  5130. #line 3660 "vm_x86.dasc"
  5131.     break;
  5132.   case BC_LEN:
  5133.     //|  ins_AD        // RA = dst, RD = src
  5134.     //|  checkstr RD, >2
  5135.     //|  mov STR:RD, [BASE+RD*8]
  5136.     //|.if DUALNUM
  5137.     //|  mov RD, dword STR:RD->len
  5138.     //|1:
  5139.     //|  mov dword [BASE+RA*8+4], LJ_TISNUM
  5140.     //|  mov dword [BASE+RA*8], RD
  5141.     //|.else
  5142.     //|  xorps xmm0, xmm0
  5143.     //|  cvtsi2sd xmm0, dword STR:RD->len
  5144.     //|1:
  5145.     //|  movsd qword [BASE+RA*8], xmm0
  5146.     //|.endif
  5147.     //|  ins_next
  5148.     //|2:
  5149.     //|  checktab RD, ->vmeta_len
  5150.     //|  mov TAB:FCARG1, [BASE+RD*8]
  5151.     dasm_put(Dst, 9923, LJ_TSTR, Dt5(->len), LJ_TISNUM, LJ_TTAB);
  5152. #line 3680 "vm_x86.dasc"
  5153. #if LJ_52
  5154.     //|  mov TAB:RB, TAB:FCARG1->metatable
  5155.     //|  cmp TAB:RB, 0
  5156.     //|  jnz >9
  5157.     //|3:
  5158.     dasm_put(Dst, 9985, Dt6(->metatable));
  5159. #line 3685 "vm_x86.dasc"
  5160. #endif
  5161.     //|->BC_LEN_Z:
  5162.     //|  mov RB, BASE                        // Save BASE.
  5163.     //|  call extern lj_tab_len@4                // (GCtab *t)
  5164.     //|  // Length of table returned in eax (RD).
  5165.     //|.if DUALNUM
  5166.     //|  // Nothing to do.
  5167.     //|.else
  5168.     //|  cvtsi2sd xmm0, RD
  5169.     //|.endif
  5170.     //|  mov BASE, RB                        // Restore BASE.
  5171.     //|  movzx RA, PC_RA
  5172.     //|  jmp <1
  5173.     dasm_put(Dst, 9999);
  5174. #line 3698 "vm_x86.dasc"
  5175. #if LJ_52
  5176.     //|9:  // Check for __len.
  5177.     //|  test byte TAB:RB->nomm, 1<<MM_len
  5178.     //|  jnz <3
  5179.     //|  jmp ->vmeta_len                        // 'no __len' flag NOT set: check.
  5180.     dasm_put(Dst, 10020, Dt6(->nomm), 1<<MM_len);
  5181. #line 3703 "vm_x86.dasc"
  5182. #endif
  5183.     break;

  5184.   /* -- Binary ops -------------------------------------------------------- */

  5185.     //|.macro ins_arithpre, sseins, ssereg
  5186.     //|  ins_ABC
  5187.     //||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5188.     //||switch (vk) {
  5189.     //||case 0:
  5190.     //|   checknum RB, ->vmeta_arith_vn
  5191.     //|   .if DUALNUM
  5192.     //|     cmp dword [KBASE+RC*8+4], LJ_TISNUM; jae ->vmeta_arith_vn
  5193.     //|   .endif
  5194.     //|   movsd xmm0, qword [BASE+RB*8]
  5195.     //|   sseins ssereg, qword [KBASE+RC*8]
  5196.     //||  break;
  5197.     //||case 1:
  5198.     //|   checknum RB, ->vmeta_arith_nv
  5199.     //|   .if DUALNUM
  5200.     //|     cmp dword [KBASE+RC*8+4], LJ_TISNUM; jae ->vmeta_arith_nv
  5201.     //|   .endif
  5202.     //|   movsd xmm0, qword [KBASE+RC*8]
  5203.     //|   sseins ssereg, qword [BASE+RB*8]
  5204.     //||  break;
  5205.     //||default:
  5206.     //|   checknum RB, ->vmeta_arith_vv
  5207.     //|   checknum RC, ->vmeta_arith_vv
  5208.     //|   movsd xmm0, qword [BASE+RB*8]
  5209.     //|   sseins ssereg, qword [BASE+RC*8]
  5210.     //||  break;
  5211.     //||}
  5212.     //|.endmacro
  5213.     //|
  5214.     //|.macro ins_arithdn, intins
  5215.     //|  ins_ABC
  5216.     //||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5217.     //||switch (vk) {
  5218.     //||case 0:
  5219.     //|   checkint RB, ->vmeta_arith_vn
  5220.     //|   cmp dword [KBASE+RC*8+4], LJ_TISNUM; jne ->vmeta_arith_vn
  5221.     //|   mov RB, [BASE+RB*8]
  5222.     //|   intins RB, [KBASE+RC*8]; jo ->vmeta_arith_vno
  5223.     //||  break;
  5224.     //||case 1:
  5225.     //|   checkint RB, ->vmeta_arith_nv
  5226.     //|   cmp dword [KBASE+RC*8+4], LJ_TISNUM; jne ->vmeta_arith_nv
  5227.     //|   mov RC, [KBASE+RC*8]
  5228.     //|   intins RC, [BASE+RB*8]; jo ->vmeta_arith_nvo
  5229.     //||  break;
  5230.     //||default:
  5231.     //|   checkint RB, ->vmeta_arith_vv
  5232.     //|   checkint RC, ->vmeta_arith_vv
  5233.     //|   mov RB, [BASE+RB*8]
  5234.     //|   intins RB, [BASE+RC*8]; jo ->vmeta_arith_vvo
  5235.     //||  break;
  5236.     //||}
  5237.     //|  mov dword [BASE+RA*8+4], LJ_TISNUM
  5238.     //||if (vk == 1) {
  5239.     //|   mov dword [BASE+RA*8], RC
  5240.     //||} else {
  5241.     //|   mov dword [BASE+RA*8], RB
  5242.     //||}
  5243.     //|  ins_next
  5244.     //|.endmacro
  5245.     //|
  5246.     //|.macro ins_arithpost
  5247.     //|  movsd qword [BASE+RA*8], xmm0
  5248.     //|.endmacro
  5249.     //|
  5250.     //|.macro ins_arith, sseins
  5251.     //|  ins_arithpre sseins, xmm0
  5252.     //|  ins_arithpost
  5253.     //|  ins_next
  5254.     //|.endmacro
  5255.     //|
  5256.     //|.macro ins_arith, intins, sseins
  5257.     //|.if DUALNUM
  5258.     //|  ins_arithdn intins
  5259.     //|.else
  5260.     //|  ins_arith, sseins
  5261.     //|.endif
  5262.     //|.endmacro

  5263.     //|  // RA = dst, RB = src1 or num const, RC = src2 or num const
  5264.   case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
  5265.     //|  ins_arith add, addsd
  5266.     dasm_put(Dst, 10036);
  5267.     vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5268.     switch (vk) {
  5269.     case 0:
  5270.     dasm_put(Dst, 10044, LJ_TISNUM, LJ_TISNUM);
  5271.       break;
  5272.     case 1:
  5273.     dasm_put(Dst, 10079, LJ_TISNUM, LJ_TISNUM);
  5274.       break;
  5275.     default:
  5276.     dasm_put(Dst, 10114, LJ_TISNUM, LJ_TISNUM);
  5277.       break;
  5278.     }
  5279.     dasm_put(Dst, 10147, LJ_TISNUM);
  5280.     if (vk == 1) {
  5281.     dasm_put(Dst, 10153);
  5282.     } else {
  5283.     dasm_put(Dst, 9654);
  5284.     }
  5285.     dasm_put(Dst, 9224);
  5286. #line 3790 "vm_x86.dasc"
  5287.     break;
  5288.   case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
  5289.     //|  ins_arith sub, subsd
  5290.     dasm_put(Dst, 10036);
  5291.     vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5292.     switch (vk) {
  5293.     case 0:
  5294.     dasm_put(Dst, 10157, LJ_TISNUM, LJ_TISNUM);
  5295.       break;
  5296.     case 1:
  5297.     dasm_put(Dst, 10192, LJ_TISNUM, LJ_TISNUM);
  5298.       break;
  5299.     default:
  5300.     dasm_put(Dst, 10227, LJ_TISNUM, LJ_TISNUM);
  5301.       break;
  5302.     }
  5303.     dasm_put(Dst, 10147, LJ_TISNUM);
  5304.     if (vk == 1) {
  5305.     dasm_put(Dst, 10153);
  5306.     } else {
  5307.     dasm_put(Dst, 9654);
  5308.     }
  5309.     dasm_put(Dst, 9224);
  5310. #line 3793 "vm_x86.dasc"
  5311.     break;
  5312.   case BC_MULVN: case BC_MULNV: case BC_MULVV:
  5313.     //|  ins_arith imul, mulsd
  5314.     dasm_put(Dst, 10036);
  5315.     vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5316.     switch (vk) {
  5317.     case 0:
  5318.     dasm_put(Dst, 10260, LJ_TISNUM, LJ_TISNUM);
  5319.       break;
  5320.     case 1:
  5321.     dasm_put(Dst, 10296, LJ_TISNUM, LJ_TISNUM);
  5322.       break;
  5323.     default:
  5324.     dasm_put(Dst, 10332, LJ_TISNUM, LJ_TISNUM);
  5325.       break;
  5326.     }
  5327.     dasm_put(Dst, 10147, LJ_TISNUM);
  5328.     if (vk == 1) {
  5329.     dasm_put(Dst, 10153);
  5330.     } else {
  5331.     dasm_put(Dst, 9654);
  5332.     }
  5333.     dasm_put(Dst, 9224);
  5334. #line 3796 "vm_x86.dasc"
  5335.     break;
  5336.   case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
  5337.     //|  ins_arith divsd
  5338.     dasm_put(Dst, 10036);
  5339.     vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5340.     switch (vk) {
  5341.     case 0:
  5342.     dasm_put(Dst, 10366, LJ_TISNUM, LJ_TISNUM);
  5343.       break;
  5344.     case 1:
  5345.     dasm_put(Dst, 10403, LJ_TISNUM, LJ_TISNUM);
  5346.       break;
  5347.     default:
  5348.     dasm_put(Dst, 10440, LJ_TISNUM, LJ_TISNUM);
  5349.       break;
  5350.     }
  5351.     dasm_put(Dst, 10475);
  5352. #line 3799 "vm_x86.dasc"
  5353.     break;
  5354.   case BC_MODVN:
  5355.     //|  ins_arithpre movsd, xmm1
  5356.     dasm_put(Dst, 10036);
  5357.     vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5358.     switch (vk) {
  5359.     case 0:
  5360.     dasm_put(Dst, 10502, LJ_TISNUM, LJ_TISNUM);
  5361.       break;
  5362.     case 1:
  5363.     dasm_put(Dst, 10539, LJ_TISNUM, LJ_TISNUM);
  5364.       break;
  5365.     default:
  5366.     dasm_put(Dst, 10576, LJ_TISNUM, LJ_TISNUM);
  5367.       break;
  5368.     }
  5369. #line 3802 "vm_x86.dasc"
  5370.     //|->BC_MODVN_Z:
  5371.     //|  call ->vm_mod
  5372.     //|  ins_arithpost
  5373.     //|  ins_next
  5374.     dasm_put(Dst, 10611);
  5375. #line 3806 "vm_x86.dasc"
  5376.     break;
  5377.   case BC_MODNV: case BC_MODVV:
  5378.     //|  ins_arithpre movsd, xmm1
  5379.     dasm_put(Dst, 10036);
  5380.     vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5381.     switch (vk) {
  5382.     case 0:
  5383.     dasm_put(Dst, 10502, LJ_TISNUM, LJ_TISNUM);
  5384.       break;
  5385.     case 1:
  5386.     dasm_put(Dst, 10539, LJ_TISNUM, LJ_TISNUM);
  5387.       break;
  5388.     default:
  5389.     dasm_put(Dst, 10576, LJ_TISNUM, LJ_TISNUM);
  5390.       break;
  5391.     }
  5392. #line 3809 "vm_x86.dasc"
  5393.     //|  jmp ->BC_MODVN_Z                        // Avoid 3 copies. It's slow anyway.
  5394.     dasm_put(Dst, 10643);
  5395. #line 3810 "vm_x86.dasc"
  5396.     break;
  5397.   case BC_POW:
  5398.     //|  ins_arithpre movsd, xmm1
  5399.     dasm_put(Dst, 10036);
  5400.     vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
  5401.     switch (vk) {
  5402.     case 0:
  5403.     dasm_put(Dst, 10502, LJ_TISNUM, LJ_TISNUM);
  5404.       break;
  5405.     case 1:
  5406.     dasm_put(Dst, 10539, LJ_TISNUM, LJ_TISNUM);
  5407.       break;
  5408.     default:
  5409.     dasm_put(Dst, 10576, LJ_TISNUM, LJ_TISNUM);
  5410.       break;
  5411.     }
  5412. #line 3813 "vm_x86.dasc"
  5413.     //|  mov RB, BASE
  5414.     //|.if not X64
  5415.     //|  movsd FPARG1, xmm0
  5416.     //|  movsd FPARG3, xmm1
  5417.     //|.endif
  5418.     //|  call extern pow
  5419.     //|  movzx RA, PC_RA
  5420.     //|  mov BASE, RB
  5421.     //|.if X64
  5422.     //|  ins_arithpost
  5423.     //|.else
  5424.     //|  fstp qword [BASE+RA*8]
  5425.     //|.endif
  5426.     //|  ins_next
  5427.     dasm_put(Dst, 10648);
  5428. #line 3827 "vm_x86.dasc"
  5429.     break;

  5430.   case BC_CAT:
  5431.     //|  ins_ABC        // RA = dst, RB = src_start, RC = src_end
  5432.     //|.if X64
  5433.     //|  mov L:CARG1d, SAVE_L
  5434.     //|  mov L:CARG1d->base, BASE
  5435.     //|  lea CARG2d, [BASE+RC*8]
  5436.     //|  mov CARG3d, RC
  5437.     //|  sub CARG3d, RB
  5438.     //|->BC_CAT_Z:
  5439.     //|  mov L:RB, L:CARG1d
  5440.     //|.else
  5441.     //|  lea RA, [BASE+RC*8]
  5442.     //|  sub RC, RB
  5443.     //|  mov ARG2, RA
  5444.     //|  mov ARG3, RC
  5445.     //|->BC_CAT_Z:
  5446.     //|  mov L:RB, SAVE_L
  5447.     //|  mov ARG1, L:RB
  5448.     //|  mov L:RB->base, BASE
  5449.     //|.endif
  5450.     //|  mov SAVE_PC, PC
  5451.     //|  call extern lj_meta_cat                // (lua_State *L, TValue *top, int left)
  5452.     //|  // NULL (finished) or TValue * (metamethod) returned in eax (RC).
  5453.     //|  mov BASE, L:RB->base
  5454.     //|  test RC, RC
  5455.     //|  jnz ->vmeta_binop
  5456.     //|  movzx RB, PC_RB                        // Copy result to Stk[RA] from Stk[RB].
  5457.     //|  movzx RA, PC_RA
  5458.     //|.if X64
  5459.     //|  mov RCa, [BASE+RB*8]
  5460.     //|  mov [BASE+RA*8], RCa
  5461.     //|.else
  5462.     //|  mov RC, [BASE+RB*8+4]
  5463.     //|  mov RB, [BASE+RB*8]
  5464.     //|  mov [BASE+RA*8+4], RC
  5465.     //|  mov [BASE+RA*8], RB
  5466.     //|.endif
  5467.     //|  ins_next
  5468.     dasm_put(Dst, 10689, Dt1(->base), Dt1(->base));
  5469. #line 3867 "vm_x86.dasc"
  5470.     break;

  5471.   /* -- Constant ops ------------------------------------------------------ */

  5472.   case BC_KSTR:
  5473.     //|  ins_AND        // RA = dst, RD = str const (~)
  5474.     //|  mov RD, [KBASE+RD*4]
  5475.     //|  mov dword [BASE+RA*8+4], LJ_TSTR
  5476.     //|  mov [BASE+RA*8], RD
  5477.     //|  ins_next
  5478.     dasm_put(Dst, 10773, LJ_TSTR);
  5479. #line 3877 "vm_x86.dasc"
  5480.     break;
  5481.   case BC_KCDATA:
  5482.     //|.if FFI
  5483.     //|  ins_AND        // RA = dst, RD = cdata const (~)
  5484.     //|  mov RD, [KBASE+RD*4]
  5485.     //|  mov dword [BASE+RA*8+4], LJ_TCDATA
  5486.     //|  mov [BASE+RA*8], RD
  5487.     //|  ins_next
  5488.     //|.endif
  5489.     dasm_put(Dst, 10773, LJ_TCDATA);
  5490. #line 3886 "vm_x86.dasc"
  5491.     break;
  5492.   case BC_KSHORT:
  5493.     //|  ins_AD        // RA = dst, RD = signed int16 literal
  5494.     //|.if DUALNUM
  5495.     //|  movsx RD, RDW
  5496.     //|  mov dword [BASE+RA*8+4], LJ_TISNUM
  5497.     //|  mov dword [BASE+RA*8], RD
  5498.     //|.else
  5499.     //|  movsx RD, RDW                        // Sign-extend literal.
  5500.     //|  cvtsi2sd xmm0, RD
  5501.     //|  movsd qword [BASE+RA*8], xmm0
  5502.     //|.endif
  5503.     //|  ins_next
  5504.     dasm_put(Dst, 10810, LJ_TISNUM);
  5505. #line 3899 "vm_x86.dasc"
  5506.     break;
  5507.   case BC_KNUM:
  5508.     //|  ins_AD        // RA = dst, RD = num const
  5509.     //|  movsd xmm0, qword [KBASE+RD*8]
  5510.     //|  movsd qword [BASE+RA*8], xmm0
  5511.     //|  ins_next
  5512.     dasm_put(Dst, 10842);
  5513. #line 3905 "vm_x86.dasc"
  5514.     break;
  5515.   case BC_KPRI:
  5516.     //|  ins_AND        // RA = dst, RD = primitive type (~)
  5517.     //|  mov [BASE+RA*8+4], RD
  5518.     //|  ins_next
  5519.     dasm_put(Dst, 10876);
  5520. #line 3910 "vm_x86.dasc"
  5521.     break;
  5522.   case BC_KNIL:
  5523.     //|  ins_AD        // RA = dst_start, RD = dst_end
  5524.     //|  lea RA, [BASE+RA*8+12]
  5525.     //|  lea RD, [BASE+RD*8+4]
  5526.     //|  mov RB, LJ_TNIL
  5527.     //|  mov [RA-8], RB                        // Sets minimum 2 slots.
  5528.     //|1:
  5529.     //|  mov [RA], RB
  5530.     //|  add RA, 8
  5531.     //|  cmp RA, RD
  5532.     //|  jbe <1
  5533.     //|  ins_next
  5534.     dasm_put(Dst, 10905, LJ_TNIL);
  5535. #line 3923 "vm_x86.dasc"
  5536.     break;

  5537.   /* -- Upvalue and function ops ------------------------------------------ */

  5538.   case BC_UGET:
  5539.     //|  ins_AD        // RA = dst, RD = upvalue #
  5540.     //|  mov LFUNC:RB, [BASE-8]
  5541.     //|  mov UPVAL:RB, [LFUNC:RB+RD*4+offsetof(GCfuncL, uvptr)]
  5542.     //|  mov RB, UPVAL:RB->v
  5543.     //|.if X64
  5544.     //|  mov RDa, [RB]
  5545.     //|  mov [BASE+RA*8], RDa
  5546.     //|.else
  5547.     //|  mov RD, [RB+4]
  5548.     //|  mov RB, [RB]
  5549.     //|  mov [BASE+RA*8+4], RD
  5550.     //|  mov [BASE+RA*8], RB
  5551.     //|.endif
  5552.     //|  ins_next
  5553.     dasm_put(Dst, 10953, offsetof(GCfuncL, uvptr), DtA(->v));
  5554. #line 3942 "vm_x86.dasc"
  5555.     break;
  5556.   case BC_USETV:
  5557. #define TV2MARKOFS \
  5558. ((int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv))
  5559.     //|  ins_AD        // RA = upvalue #, RD = src
  5560.     //|  mov LFUNC:RB, [BASE-8]
  5561.     //|  mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
  5562.     //|  cmp byte UPVAL:RB->closed, 0
  5563.     //|  mov RB, UPVAL:RB->v
  5564.     //|  mov RA, [BASE+RD*8]
  5565.     //|  mov RD, [BASE+RD*8+4]
  5566.     //|  mov [RB], RA
  5567.     //|  mov [RB+4], RD
  5568.     //|  jz >1
  5569.     //|  // Check barrier for closed upvalue.
  5570.     //|  test byte [RB+TV2MARKOFS], LJ_GC_BLACK                // isblack(uv)
  5571.     //|  jnz >2
  5572.     //|1:
  5573.     //|  ins_next
  5574.     //|
  5575.     //|2:  // Upvalue is black. Check if new value is collectable and white.
  5576.     //|  sub RD, LJ_TISGCV
  5577.     //|  cmp RD, LJ_TNUMX - LJ_TISGCV                        // tvisgcv(v)
  5578.     //|  jbe <1
  5579.     //|  test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES        // iswhite(v)
  5580.     //|  jz <1
  5581.     //|  // Crossed a write barrier. Move the barrier forward.
  5582.     //|.if X64 and not X64WIN
  5583.     //|  mov FCARG2, RB
  5584.     //|  mov RB, BASE                        // Save BASE.
  5585.     //|.else
  5586.     //|  xchg FCARG2, RB                        // Save BASE (FCARG2 == BASE).
  5587.     //|.endif
  5588.     //|  lea GL:FCARG1, [DISPATCH+GG_DISP2G]
  5589.     //|  call extern lj_gc_barrieruv@8        // (global_State *g, TValue *tv)
  5590.     dasm_put(Dst, 10994, offsetof(GCfuncL, uvptr), DtA(->closed), DtA(->v), TV2MARKOFS, LJ_GC_BLACK, LJ_TISGCV, LJ_TNUMX - LJ_TISGCV, Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
  5591. #line 3977 "vm_x86.dasc"
  5592.     //|  mov BASE, RB                        // Restore BASE.
  5593.     //|  jmp <1
  5594.     dasm_put(Dst, 11090);
  5595. #line 3979 "vm_x86.dasc"
  5596.     break;
  5597. #undef TV2MARKOFS
  5598.   case BC_USETS:
  5599.     //|  ins_AND        // RA = upvalue #, RD = str const (~)
  5600.     //|  mov LFUNC:RB, [BASE-8]
  5601.     //|  mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
  5602.     //|  mov GCOBJ:RA, [KBASE+RD*4]
  5603.     //|  mov RD, UPVAL:RB->v
  5604.     //|  mov [RD], GCOBJ:RA
  5605.     //|  mov dword [RD+4], LJ_TSTR
  5606.     //|  test byte UPVAL:RB->marked, LJ_GC_BLACK                // isblack(uv)
  5607.     //|  jnz >2
  5608.     //|1:
  5609.     //|  ins_next
  5610.     //|
  5611.     //|2:  // Check if string is white and ensure upvalue is closed.
  5612.     //|  test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES        // iswhite(str)
  5613.     //|  jz <1
  5614.     //|  cmp byte UPVAL:RB->closed, 0
  5615.     //|  jz <1
  5616.     //|  // Crossed a write barrier. Move the barrier forward.
  5617.     //|  mov RB, BASE                        // Save BASE (FCARG2 == BASE).
  5618.     //|  mov FCARG2, RD
  5619.     //|  lea GL:FCARG1, [DISPATCH+GG_DISP2G]
  5620.     //|  call extern lj_gc_barrieruv@8        // (global_State *g, TValue *tv)
  5621.     //|  mov BASE, RB                        // Restore BASE.
  5622.     //|  jmp <1
  5623.     dasm_put(Dst, 11102, offsetof(GCfuncL, uvptr), DtA(->v), LJ_TSTR, DtA(->marked), LJ_GC_BLACK, Dt4(->gch.marked), LJ_GC_WHITES, DtA(->closed), GG_DISP2G);
  5624. #line 4006 "vm_x86.dasc"
  5625.     break;
  5626.   case BC_USETN:
  5627.     //|  ins_AD        // RA = upvalue #, RD = num const
  5628.     //|  mov LFUNC:RB, [BASE-8]
  5629.     //|  movsd xmm0, qword [KBASE+RD*8]
  5630.     //|  mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
  5631.     //|  mov RA, UPVAL:RB->v
  5632.     //|  movsd qword [RA], xmm0
  5633.     //|  ins_next
  5634.     dasm_put(Dst, 11198, offsetof(GCfuncL, uvptr), DtA(->v));
  5635. #line 4015 "vm_x86.dasc"
  5636.     break;
  5637.   case BC_USETP:
  5638.     //|  ins_AND        // RA = upvalue #, RD = primitive type (~)
  5639.     //|  mov LFUNC:RB, [BASE-8]
  5640.     //|  mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
  5641.     //|  mov RA, UPVAL:RB->v
  5642.     //|  mov [RA+4], RD
  5643.     //|  ins_next
  5644.     dasm_put(Dst, 11243, offsetof(GCfuncL, uvptr), DtA(->v));
  5645. #line 4023 "vm_x86.dasc"
  5646.     break;
  5647.   case BC_UCLO:
  5648.     //|  ins_AD        // RA = level, RD = target
  5649.     //|  branchPC RD                        // Do this first to free RD.
  5650.     //|  mov L:RB, SAVE_L
  5651.     //|  cmp dword L:RB->openupval, 0
  5652.     //|  je >1
  5653.     //|  mov L:RB->base, BASE
  5654.     //|  lea FCARG2, [BASE+RA*8]                // Caveat: FCARG2 == BASE
  5655.     //|  mov L:FCARG1, L:RB                // Caveat: FCARG1 == RA
  5656.     //|  call extern lj_func_closeuv@8        // (lua_State *L, TValue *level)
  5657.     //|  mov BASE, L:RB->base
  5658.     //|1:
  5659.     //|  ins_next
  5660.     dasm_put(Dst, 11283, -BCBIAS_J*4, Dt1(->openupval), Dt1(->base), Dt1(->base));
  5661. #line 4037 "vm_x86.dasc"
  5662.     break;

  5663.   case BC_FNEW:
  5664.     //|  ins_AND        // RA = dst, RD = proto const (~) (holding function prototype)
  5665.     //|.if X64
  5666.     //|  mov L:RB, SAVE_L
  5667.     //|  mov L:RB->base, BASE                // Caveat: CARG2d/CARG3d may be BASE.
  5668.     //|  mov CARG3d, [BASE-8]
  5669.     //|  mov CARG2d, [KBASE+RD*4]                // Fetch GCproto *.
  5670.     //|  mov CARG1d, L:RB
  5671.     //|.else
  5672.     //|  mov LFUNC:RA, [BASE-8]
  5673.     //|  mov PROTO:RD, [KBASE+RD*4]        // Fetch GCproto *.
  5674.     //|  mov L:RB, SAVE_L
  5675.     //|  mov ARG3, LFUNC:RA
  5676.     //|  mov ARG2, PROTO:RD
  5677.     //|  mov ARG1, L:RB
  5678.     //|  mov L:RB->base, BASE
  5679.     //|.endif
  5680.     //|  mov SAVE_PC, PC
  5681.     //|  // (lua_State *L, GCproto *pt, GCfuncL *parent)
  5682.     //|  call extern lj_func_newL_gc
  5683.     //|  // GCfuncL * returned in eax (RC).
  5684.     //|  mov BASE, L:RB->base
  5685.     //|  movzx RA, PC_RA
  5686.     //|  mov [BASE+RA*8], LFUNC:RC
  5687.     //|  mov dword [BASE+RA*8+4], LJ_TFUNC
  5688.     //|  ins_next
  5689.     dasm_put(Dst, 11339, Dt1(->base), Dt1(->base), LJ_TFUNC);
  5690. #line 4065 "vm_x86.dasc"
  5691.     break;

  5692.   /* -- Table ops --------------------------------------------------------- */

  5693.   case BC_TNEW:
  5694.     //|  ins_AD        // RA = dst, RD = hbits|asize
  5695.     //|  mov L:RB, SAVE_L
  5696.     //|  mov L:RB->base, BASE
  5697.     //|  mov RA, [DISPATCH+DISPATCH_GL(gc.total)]
  5698.     //|  cmp RA, [DISPATCH+DISPATCH_GL(gc.threshold)]
  5699.     //|  mov SAVE_PC, PC
  5700.     //|  jae >5
  5701.     //|1:
  5702.     //|.if X64
  5703.     //|  mov CARG3d, RD
  5704.     //|  and RD, 0x7ff
  5705.     //|  shr CARG3d, 11
  5706.     //|.else
  5707.     //|  mov RA, RD
  5708.     //|  and RD, 0x7ff
  5709.     //|  shr RA, 11
  5710.     //|  mov ARG3, RA
  5711.     //|.endif
  5712.     //|  cmp RD, 0x7ff
  5713.     //|  je >3
  5714.     //|2:
  5715.     //|.if X64
  5716.     //|  mov L:CARG1d, L:RB
  5717.     //|  mov CARG2d, RD
  5718.     //|.else
  5719.     //|  mov ARG1, L:RB
  5720.     //|  mov ARG2, RD
  5721.     //|.endif
  5722.     //|  call extern lj_tab_new  // (lua_State *L, int32_t asize, uint32_t hbits)
  5723.     //|  // Table * returned in eax (RC).
  5724.     //|  mov BASE, L:RB->base
  5725.     //|  movzx RA, PC_RA
  5726.     //|  mov [BASE+RA*8], TAB:RC
  5727.     //|  mov dword [BASE+RA*8+4], LJ_TTAB
  5728.     //|  ins_next
  5729.     //|3:  // Turn 0x7ff into 0x801.
  5730.     //|  mov RD, 0x801
  5731.     //|  jmp <2
  5732.     //|5:
  5733.     //|  mov L:FCARG1, L:RB
  5734.     //|  call extern lj_gc_step_fixtop@4        // (lua_State *L)
  5735.     //|  movzx RD, PC_RD
  5736.     //|  jmp <1
  5737.     dasm_put(Dst, 11406, Dt1(->base), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), LJ_TTAB);
  5738. #line 4113 "vm_x86.dasc"
  5739.     break;
  5740.   case BC_TDUP:
  5741.     //|  ins_AND        // RA = dst, RD = table const (~) (holding template table)
  5742.     //|  mov L:RB, SAVE_L
  5743.     //|  mov RA, [DISPATCH+DISPATCH_GL(gc.total)]
  5744.     //|  mov SAVE_PC, PC
  5745.     //|  cmp RA, [DISPATCH+DISPATCH_GL(gc.threshold)]
  5746.     //|  mov L:RB->base, BASE
  5747.     //|  jae >3
  5748.     //|2:
  5749.     //|  mov TAB:FCARG2, [KBASE+RD*4]        // Caveat: FCARG2 == BASE
  5750.     //|  mov L:FCARG1, L:RB                // Caveat: FCARG1 == RA
  5751.     //|  call extern lj_tab_dup@8                // (lua_State *L, Table *kt)
  5752.     //|  // Table * returned in eax (RC).
  5753.     //|  mov BASE, L:RB->base
  5754.     //|  movzx RA, PC_RA
  5755.     //|  mov [BASE+RA*8], TAB:RC
  5756.     //|  mov dword [BASE+RA*8+4], LJ_TTAB
  5757.     //|  ins_next
  5758.     //|3:
  5759.     //|  mov L:FCARG1, L:RB
  5760.     //|  call extern lj_gc_step_fixtop@4        // (lua_State *L)
  5761.     //|  movzx RD, PC_RD                        // Need to reload RD.
  5762.     //|  not RDa
  5763.     //|  jmp <2
  5764.     dasm_put(Dst, 11530, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), Dt1(->base), LJ_TTAB);
  5765. #line 4138 "vm_x86.dasc"
  5766.     break;

  5767.   case BC_GGET:
  5768.     //|  ins_AND        // RA = dst, RD = str const (~)
  5769.     //|  mov LFUNC:RB, [BASE-8]
  5770.     //|  mov TAB:RB, LFUNC:RB->env
  5771.     //|  mov STR:RC, [KBASE+RD*4]
  5772.     //|  jmp ->BC_TGETS_Z
  5773.     dasm_put(Dst, 11629, Dt7(->env));
  5774. #line 4146 "vm_x86.dasc"
  5775.     break;
  5776.   case BC_GSET:
  5777.     //|  ins_AND        // RA = src, RD = str const (~)
  5778.     //|  mov LFUNC:RB, [BASE-8]
  5779.     //|  mov TAB:RB, LFUNC:RB->env
  5780.     //|  mov STR:RC, [KBASE+RD*4]
  5781.     //|  jmp ->BC_TSETS_Z
  5782.     dasm_put(Dst, 11649, Dt7(->env));
  5783. #line 4153 "vm_x86.dasc"
  5784.     break;

  5785.   case BC_TGETV:
  5786.     //|  ins_ABC        // RA = dst, RB = table, RC = key
  5787.     //|  checktab RB, ->vmeta_tgetv
  5788.     //|  mov TAB:RB, [BASE+RB*8]
  5789.     //|
  5790.     //|  // Integer key?
  5791.     //|.if DUALNUM
  5792.     //|  checkint RC, >5
  5793.     //|  mov RC, dword [BASE+RC*8]
  5794.     //|.else
  5795.     //|  // Convert number to int and back and compare.
  5796.     //|  checknum RC, >5
  5797.     //|  movsd xmm0, qword [BASE+RC*8]
  5798.     //|  cvttsd2si RC, xmm0
  5799.     //|  cvtsi2sd xmm1, RC
  5800.     //|  ucomisd xmm0, xmm1
  5801.     //|  jne ->vmeta_tgetv                // Generic numeric key? Use fallback.
  5802.     //|.endif
  5803.     //|  cmp RC, TAB:RB->asize        // Takes care of unordered, too.
  5804.     //|  jae ->vmeta_tgetv                // Not in array part? Use fallback.
  5805.     //|  shl RC, 3
  5806.     //|  add RC, TAB:RB->array
  5807.     //|  cmp dword [RC+4], LJ_TNIL        // Avoid overwriting RB in fastpath.
  5808.     //|  je >2
  5809.     //|  // Get array slot.
  5810.     //|.if X64
  5811.     //|  mov RBa, [RC]
  5812.     //|  mov [BASE+RA*8], RBa
  5813.     //|.else
  5814.     //|  mov RB, [RC]
  5815.     //|  mov RC, [RC+4]
  5816.     //|  mov [BASE+RA*8], RB
  5817.     //|  mov [BASE+RA*8+4], RC
  5818.     //|.endif
  5819.     //|1:
  5820.     //|  ins_next
  5821.     //|
  5822.     //|2:  // Check for __index if table value is nil.
  5823.     //|  cmp dword TAB:RB->metatable, 0        // Shouldn't overwrite RA for fastpath.
  5824.     //|  jz >3
  5825.     //|  mov TAB:RA, TAB:RB->metatable
  5826.     //|  test byte TAB:RA->nomm, 1<<MM_index
  5827.     //|  jz ->vmeta_tgetv                        // 'no __index' flag NOT set: check.
  5828.     dasm_put(Dst, 11669, LJ_TTAB, LJ_TISNUM, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
  5829. #line 4198 "vm_x86.dasc"
  5830.     //|  movzx RA, PC_RA                        // Restore RA.
  5831.     //|3:
  5832.     //|  mov dword [BASE+RA*8+4], LJ_TNIL
  5833.     //|  jmp <1
  5834.     //|
  5835.     //|5:  // String key?
  5836.     //|  checkstr RC, ->vmeta_tgetv
  5837.     //|  mov STR:RC, [BASE+RC*8]
  5838.     //|  jmp ->BC_TGETS_Z
  5839.     dasm_put(Dst, 11774, LJ_TNIL, LJ_TSTR);
  5840. #line 4207 "vm_x86.dasc"
  5841.     break;
  5842.   case BC_TGETS:
  5843.     //|  ins_ABC        // RA = dst, RB = table, RC = str const (~)
  5844.     //|  not RCa
  5845.     //|  mov STR:RC, [KBASE+RC*4]
  5846.     //|  checktab RB, ->vmeta_tgets
  5847.     //|  mov TAB:RB, [BASE+RB*8]
  5848.     //|->BC_TGETS_Z:        // RB = GCtab *, RC = GCstr *, refetches PC_RA.
  5849.     //|  mov RA, TAB:RB->hmask
  5850.     //|  and RA, STR:RC->hash
  5851.     //|  imul RA, #NODE
  5852.     //|  add NODE:RA, TAB:RB->node
  5853.     //|1:
  5854.     //|  cmp dword NODE:RA->key.it, LJ_TSTR
  5855.     //|  jne >4
  5856.     //|  cmp dword NODE:RA->key.gcr, STR:RC
  5857.     //|  jne >4
  5858.     //|  // Ok, key found. Assumes: offsetof(Node, val) == 0
  5859.     //|  cmp dword [RA+4], LJ_TNIL        // Avoid overwriting RB in fastpath.
  5860.     //|  je >5                                // Key found, but nil value?
  5861.     //|  movzx RC, PC_RA
  5862.     //|  // Get node value.
  5863.     //|.if X64
  5864.     //|  mov RBa, [RA]
  5865.     //|  mov [BASE+RC*8], RBa
  5866.     //|.else
  5867.     //|  mov RB, [RA]
  5868.     //|  mov RA, [RA+4]
  5869.     //|  mov [BASE+RC*8], RB
  5870.     //|  mov [BASE+RC*8+4], RA
  5871.     //|.endif
  5872.     //|2:
  5873.     //|  ins_next
  5874.     dasm_put(Dst, 11814, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
  5875. #line 4240 "vm_x86.dasc"
  5876.     //|
  5877.     //|3:
  5878.     //|  movzx RC, PC_RA
  5879.     //|  mov dword [BASE+RC*8+4], LJ_TNIL
  5880.     //|  jmp <2
  5881.     //|
  5882.     //|4:  // Follow hash chain.
  5883.     //|  mov NODE:RA, NODE:RA->next
  5884.     //|  test NODE:RA, NODE:RA
  5885.     //|  jnz <1
  5886.     //|  // End of hash chain: key not found, nil result.
  5887.     //|
  5888.     //|5:  // Check for __index if table value is nil.
  5889.     //|  mov TAB:RA, TAB:RB->metatable
  5890.     //|  test TAB:RA, TAB:RA
  5891.     //|  jz <3                                // No metatable: done.
  5892.     //|  test byte TAB:RA->nomm, 1<<MM_index
  5893.     //|  jnz <3                                // 'no __index' flag set: done.
  5894.     //|  jmp ->vmeta_tgets                // Caveat: preserve STR:RC.
  5895.     dasm_put(Dst, 11899, LJ_TNIL, DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
  5896. #line 4259 "vm_x86.dasc"
  5897.     break;
  5898.   case BC_TGETB:
  5899.     //|  ins_ABC        // RA = dst, RB = table, RC = byte literal
  5900.     //|  checktab RB, ->vmeta_tgetb
  5901.     //|  mov TAB:RB, [BASE+RB*8]
  5902.     //|  cmp RC, TAB:RB->asize
  5903.     //|  jae ->vmeta_tgetb
  5904.     //|  shl RC, 3
  5905.     //|  add RC, TAB:RB->array
  5906.     //|  cmp dword [RC+4], LJ_TNIL        // Avoid overwriting RB in fastpath.
  5907.     //|  je >2
  5908.     //|  // Get array slot.
  5909.     //|.if X64
  5910.     //|  mov RBa, [RC]
  5911.     //|  mov [BASE+RA*8], RBa
  5912.     //|.else
  5913.     //|  mov RB, [RC]
  5914.     //|  mov RC, [RC+4]
  5915.     //|  mov [BASE+RA*8], RB
  5916.     //|  mov [BASE+RA*8+4], RC
  5917.     //|.endif
  5918.     //|1:
  5919.     //|  ins_next
  5920.     //|
  5921.     //|2:  // Check for __index if table value is nil.
  5922.     //|  cmp dword TAB:RB->metatable, 0        // Shouldn't overwrite RA for fastpath.
  5923.     //|  jz >3
  5924.     //|  mov TAB:RA, TAB:RB->metatable
  5925.     //|  test byte TAB:RA->nomm, 1<<MM_index
  5926.     //|  jz ->vmeta_tgetb                        // 'no __index' flag NOT set: check.
  5927.     //|  movzx RA, PC_RA                        // Restore RA.
  5928.     dasm_put(Dst, 11971, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
  5929. #line 4290 "vm_x86.dasc"
  5930.     //|3:
  5931.     //|  mov dword [BASE+RA*8+4], LJ_TNIL
  5932.     //|  jmp <1
  5933.     dasm_put(Dst, 12067, LJ_TNIL);
  5934. #line 4293 "vm_x86.dasc"
  5935.     break;
  5936.   case BC_TGETR:
  5937.     //|  ins_ABC        // RA = dst, RB = table, RC = key
  5938.     //|  mov TAB:RB, [BASE+RB*8]
  5939.     //|.if DUALNUM
  5940.     //|  mov RC, dword [BASE+RC*8]
  5941.     //|.else
  5942.     //|  cvttsd2si RC, qword [BASE+RC*8]
  5943.     //|.endif
  5944.     //|  cmp RC, TAB:RB->asize
  5945.     //|  jae ->vmeta_tgetr                // Not in array part? Use fallback.
  5946.     //|  shl RC, 3
  5947.     //|  add RC, TAB:RB->array
  5948.     //|  // Get array slot.
  5949.     //|->BC_TGETR_Z:
  5950.     //|.if X64
  5951.     //|  mov RBa, [RC]
  5952.     //|  mov [BASE+RA*8], RBa
  5953.     //|.else
  5954.     //|  mov RB, [RC]
  5955.     //|  mov RC, [RC+4]
  5956.     //|  mov [BASE+RA*8], RB
  5957.     //|  mov [BASE+RA*8+4], RC
  5958.     //|.endif
  5959.     //|->BC_TGETR2_Z:
  5960.     //|  ins_next
  5961.     dasm_put(Dst, 12084, Dt6(->asize), Dt6(->array));
  5962. #line 4319 "vm_x86.dasc"
  5963.     break;

  5964.   case BC_TSETV:
  5965.     //|  ins_ABC        // RA = src, RB = table, RC = key
  5966.     //|  checktab RB, ->vmeta_tsetv
  5967.     //|  mov TAB:RB, [BASE+RB*8]
  5968.     //|
  5969.     //|  // Integer key?
  5970.     //|.if DUALNUM
  5971.     //|  checkint RC, >5
  5972.     //|  mov RC, dword [BASE+RC*8]
  5973.     //|.else
  5974.     //|  // Convert number to int and back and compare.
  5975.     //|  checknum RC, >5
  5976.     //|  movsd xmm0, qword [BASE+RC*8]
  5977.     //|  cvttsd2si RC, xmm0
  5978.     //|  cvtsi2sd xmm1, RC
  5979.     //|  ucomisd xmm0, xmm1
  5980.     //|  jne ->vmeta_tsetv                // Generic numeric key? Use fallback.
  5981.     //|.endif
  5982.     //|  cmp RC, TAB:RB->asize                // Takes care of unordered, too.
  5983.     //|  jae ->vmeta_tsetv
  5984.     //|  shl RC, 3
  5985.     //|  add RC, TAB:RB->array
  5986.     //|  cmp dword [RC+4], LJ_TNIL
  5987.     //|  je >3                                // Previous value is nil?
  5988.     //|1:
  5989.     //|  test byte TAB:RB->marked, LJ_GC_BLACK        // isblack(table)
  5990.     //|  jnz >7
  5991.     //|2:  // Set array slot.
  5992.     //|.if X64
  5993.     //|  mov RBa, [BASE+RA*8]
  5994.     //|  mov [RC], RBa
  5995.     //|.else
  5996.     //|  mov RB, [BASE+RA*8+4]
  5997.     //|  mov RA, [BASE+RA*8]
  5998.     //|  mov [RC+4], RB
  5999.     //|  mov [RC], RA
  6000.     //|.endif
  6001.     //|  ins_next
  6002.     //|
  6003.     //|3:  // Check for __newindex if previous value is nil.
  6004.     //|  cmp dword TAB:RB->metatable, 0        // Shouldn't overwrite RA for fastpath.
  6005.     dasm_put(Dst, 12143, LJ_TTAB, LJ_TISNUM, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK);
  6006. #line 4362 "vm_x86.dasc"
  6007.     //|  jz <1
  6008.     //|  mov TAB:RA, TAB:RB->metatable
  6009.     //|  test byte TAB:RA->nomm, 1<<MM_newindex
  6010.     //|  jz ->vmeta_tsetv                        // 'no __newindex' flag NOT set: check.
  6011.     //|  movzx RA, PC_RA                        // Restore RA.
  6012.     //|  jmp <1
  6013.     //|
  6014.     //|5:  // String key?
  6015.     //|  checkstr RC, ->vmeta_tsetv
  6016.     //|  mov STR:RC, [BASE+RC*8]
  6017.     //|  jmp ->BC_TSETS_Z
  6018.     //|
  6019.     //|7:  // Possible table write barrier for the value. Skip valiswhite check.
  6020.     //|  barrierback TAB:RB, RA
  6021.     dasm_put(Dst, 12243, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, LJ_TSTR, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain));
  6022. #line 4376 "vm_x86.dasc"
  6023.     //|  movzx RA, PC_RA                        // Restore RA.
  6024.     //|  jmp <2
  6025.     dasm_put(Dst, 12302, DISPATCH_GL(gc.grayagain), Dt6(->gclist));
  6026. #line 4378 "vm_x86.dasc"
  6027.     break;
  6028.   case BC_TSETS:
  6029.     //|  ins_ABC        // RA = src, RB = table, RC = str const (~)
  6030.     //|  not RCa
  6031.     //|  mov STR:RC, [KBASE+RC*4]
  6032.     //|  checktab RB, ->vmeta_tsets
  6033.     //|  mov TAB:RB, [BASE+RB*8]
  6034.     //|->BC_TSETS_Z:        // RB = GCtab *, RC = GCstr *, refetches PC_RA.
  6035.     //|  mov RA, TAB:RB->hmask
  6036.     //|  and RA, STR:RC->hash
  6037.     //|  imul RA, #NODE
  6038.     //|  mov byte TAB:RB->nomm, 0                // Clear metamethod cache.
  6039.     //|  add NODE:RA, TAB:RB->node
  6040.     //|1:
  6041.     //|  cmp dword NODE:RA->key.it, LJ_TSTR
  6042.     //|  jne >5
  6043.     //|  cmp dword NODE:RA->key.gcr, STR:RC
  6044.     //|  jne >5
  6045.     //|  // Ok, key found. Assumes: offsetof(Node, val) == 0
  6046.     //|  cmp dword [RA+4], LJ_TNIL
  6047.     //|  je >4                                // Previous value is nil?
  6048.     //|2:
  6049.     //|  test byte TAB:RB->marked, LJ_GC_BLACK        // isblack(table)
  6050.     dasm_put(Dst, 12319, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->nomm), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
  6051. #line 4401 "vm_x86.dasc"
  6052.     //|  jnz >7
  6053.     //|3:  // Set node value.
  6054.     //|  movzx RC, PC_RA
  6055.     //|.if X64
  6056.     //|  mov RBa, [BASE+RC*8]
  6057.     //|  mov [RA], RBa
  6058.     //|.else
  6059.     //|  mov RB, [BASE+RC*8+4]
  6060.     //|  mov RC, [BASE+RC*8]
  6061.     //|  mov [RA+4], RB
  6062.     //|  mov [RA], RC
  6063.     //|.endif
  6064.     //|  ins_next
  6065.     //|
  6066.     //|4:  // Check for __newindex if previous value is nil.
  6067.     //|  cmp dword TAB:RB->metatable, 0        // Shouldn't overwrite RA for fastpath.
  6068.     //|  jz <2
  6069.     //|  mov TMP1, RA                        // Save RA.
  6070.     //|  mov TAB:RA, TAB:RB->metatable
  6071.     //|  test byte TAB:RA->nomm, 1<<MM_newindex
  6072.     //|  jz ->vmeta_tsets                        // 'no __newindex' flag NOT set: check.
  6073.     //|  mov RA, TMP1                        // Restore RA.
  6074.     //|  jmp <2
  6075.     //|
  6076.     //|5:  // Follow hash chain.
  6077.     //|  mov NODE:RA, NODE:RA->next
  6078.     //|  test NODE:RA, NODE:RA
  6079.     //|  jnz <1
  6080.     //|  // End of hash chain: key not found, add a new one.
  6081.     //|
  6082.     //|  // But check for __newindex first.
  6083.     //|  mov TAB:RA, TAB:RB->metatable
  6084.     dasm_put(Dst, 12396, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DtB(->next));
  6085. #line 4433 "vm_x86.dasc"
  6086.     //|  test TAB:RA, TAB:RA
  6087.     //|  jz >6                                // No metatable: continue.
  6088.     //|  test byte TAB:RA->nomm, 1<<MM_newindex
  6089.     //|  jz ->vmeta_tsets                        // 'no __newindex' flag NOT set: check.
  6090.     //|6:
  6091.     //|  mov TMP1, STR:RC
  6092.     //|  mov TMP2, LJ_TSTR
  6093.     //|  mov TMP3, TAB:RB                        // Save TAB:RB for us.
  6094.     //|.if X64
  6095.     //|  mov L:CARG1d, SAVE_L
  6096.     //|  mov L:CARG1d->base, BASE
  6097.     //|  lea CARG3, TMP1
  6098.     //|  mov CARG2d, TAB:RB
  6099.     //|  mov L:RB, L:CARG1d
  6100.     //|.else
  6101.     //|  lea RC, TMP1                        // Store temp. TValue in TMP1/TMP2.
  6102.     //|  mov ARG2, TAB:RB
  6103.     //|  mov L:RB, SAVE_L
  6104.     //|  mov ARG3, RC
  6105.     //|  mov ARG1, L:RB
  6106.     //|  mov L:RB->base, BASE
  6107.     //|.endif
  6108.     //|  mov SAVE_PC, PC
  6109.     //|  call extern lj_tab_newkey        // (lua_State *L, GCtab *t, TValue *k)
  6110.     //|  // Handles write barrier for the new key. TValue * returned in eax (RC).
  6111.     //|  mov BASE, L:RB->base
  6112.     //|  mov TAB:RB, TMP3                        // Need TAB:RB for barrier.
  6113.     //|  mov RA, eax
  6114.     //|  jmp <2                                // Must check write barrier for value.
  6115.     //|
  6116.     //|7:  // Possible table write barrier for the value. Skip valiswhite check.
  6117.     //|  barrierback TAB:RB, RC                // Destroys STR:RC.
  6118.     //|  jmp <3
  6119.     dasm_put(Dst, 12483, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, LJ_TSTR, Dt1(->base), Dt1(->base), Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
  6120. #line 4466 "vm_x86.dasc"
  6121.     break;
  6122.   case BC_TSETB:
  6123.     //|  ins_ABC        // RA = src, RB = table, RC = byte literal
  6124.     //|  checktab RB, ->vmeta_tsetb
  6125.     //|  mov TAB:RB, [BASE+RB*8]
  6126.     //|  cmp RC, TAB:RB->asize
  6127.     //|  jae ->vmeta_tsetb
  6128.     //|  shl RC, 3
  6129.     //|  add RC, TAB:RB->array
  6130.     //|  cmp dword [RC+4], LJ_TNIL
  6131.     //|  je >3                                // Previous value is nil?
  6132.     //|1:
  6133.     //|  test byte TAB:RB->marked, LJ_GC_BLACK        // isblack(table)
  6134.     //|  jnz >7
  6135.     //|2:         // Set array slot.
  6136.     //|.if X64
  6137.     //|  mov RAa, [BASE+RA*8]
  6138.     //|  mov [RC], RAa
  6139.     //|.else
  6140.     //|  mov RB, [BASE+RA*8+4]
  6141.     //|  mov RA, [BASE+RA*8]
  6142.     //|  mov [RC+4], RB
  6143.     //|  mov [RC], RA
  6144.     //|.endif
  6145.     //|  ins_next
  6146.     //|
  6147.     //|3:  // Check for __newindex if previous value is nil.
  6148.     //|  cmp dword TAB:RB->metatable, 0        // Shouldn't overwrite RA for fastpath.
  6149.     //|  jz <1
  6150.     //|  mov TAB:RA, TAB:RB->metatable
  6151.     dasm_put(Dst, 12575, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable));
  6152. #line 4496 "vm_x86.dasc"
  6153.     //|  test byte TAB:RA->nomm, 1<<MM_newindex
  6154.     //|  jz ->vmeta_tsetb                        // 'no __newindex' flag NOT set: check.
  6155.     //|  movzx RA, PC_RA                        // Restore RA.
  6156.     //|  jmp <1
  6157.     //|
  6158.     //|7:  // Possible table write barrier for the value. Skip valiswhite check.
  6159.     //|  barrierback TAB:RB, RA
  6160.     //|  movzx RA, PC_RA                        // Restore RA.
  6161.     //|  jmp <2
  6162.     dasm_put(Dst, 12670, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
  6163. #line 4505 "vm_x86.dasc"
  6164.     break;
  6165.   case BC_TSETR:
  6166.     //|  ins_ABC        // RA = src, RB = table, RC = key
  6167.     //|  mov TAB:RB, [BASE+RB*8]
  6168.     //|.if DUALNUM
  6169.     //|  mov RC, dword [BASE+RC*8]
  6170.     //|.else
  6171.     //|  cvttsd2si RC, qword [BASE+RC*8]
  6172.     //|.endif
  6173.     //|  test byte TAB:RB->marked, LJ_GC_BLACK        // isblack(table)
  6174.     //|  jnz >7
  6175.     //|2:
  6176.     //|  cmp RC, TAB:RB->asize
  6177.     //|  jae ->vmeta_tsetr
  6178.     //|  shl RC, 3
  6179.     //|  add RC, TAB:RB->array
  6180.     //|  // Set array slot.
  6181.     //|->BC_TSETR_Z:
  6182.     //|.if X64
  6183.     //|  mov RBa, [BASE+RA*8]
  6184.     //|  mov [RC], RBa
  6185.     //|.else
  6186.     //|  mov RB, [BASE+RA*8+4]
  6187.     //|  mov RA, [BASE+RA*8]
  6188.     //|  mov [RC+4], RB
  6189.     //|  mov [RC], RA
  6190.     //|.endif
  6191.     //|  ins_next
  6192.     //|
  6193.     //|7:  // Possible table write barrier for the value. Skip valiswhite check.
  6194.     //|  barrierback TAB:RB, RA
  6195.     //|  movzx RA, PC_RA                        // Restore RA.
  6196.     //|  jmp <2
  6197.     dasm_put(Dst, 12718, Dt6(->marked), LJ_GC_BLACK, Dt6(->asize), Dt6(->array), Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
  6198. #line 4538 "vm_x86.dasc"
  6199.     break;

  6200.   case BC_TSETM:
  6201.     //|  ins_AD        // RA = base (table at base-1), RD = num const (start index)
  6202.     //|  mov TMP1, KBASE                        // Need one more free register.
  6203.     //|  mov KBASE, dword [KBASE+RD*8]        // Integer constant is in lo-word.
  6204.     //|1:
  6205.     //|  lea RA, [BASE+RA*8]
  6206.     //|  mov TAB:RB, [RA-8]                // Guaranteed to be a table.
  6207.     //|  test byte TAB:RB->marked, LJ_GC_BLACK        // isblack(table)
  6208.     //|  jnz >7
  6209.     //|2:
  6210.     //|  mov RD, MULTRES
  6211.     //|  sub RD, 1
  6212.     //|  jz >4                                // Nothing to copy?
  6213.     //|  add RD, KBASE                        // Compute needed size.
  6214.     //|  cmp RD, TAB:RB->asize
  6215.     //|  ja >5                                // Doesn't fit into array part?
  6216.     //|  sub RD, KBASE
  6217.     //|  shl KBASE, 3
  6218.     //|  add KBASE, TAB:RB->array
  6219.     //|3:  // Copy result slots to table.
  6220.     //|.if X64
  6221.     //|  mov RBa, [RA]
  6222.     //|  add RA, 8
  6223.     //|  mov [KBASE], RBa
  6224.     //|.else
  6225.     //|  mov RB, [RA]
  6226.     //|  mov [KBASE], RB
  6227.     //|  mov RB, [RA+4]
  6228.     //|  add RA, 8
  6229.     //|  mov [KBASE+4], RB
  6230.     //|.endif
  6231.     //|  add KBASE, 8
  6232.     //|  sub RD, 1
  6233.     //|  jnz <3
  6234.     //|4:
  6235.     //|  mov KBASE, TMP1
  6236.     //|  ins_next
  6237.     //|
  6238.     //|5:  // Need to resize array part.
  6239.     //|.if X64
  6240.     //|  mov L:CARG1d, SAVE_L
  6241.     //|  mov L:CARG1d->base, BASE                // Caveat: CARG2d/CARG3d may be BASE.
  6242.     //|  mov CARG2d, TAB:RB
  6243.     //|  mov CARG3d, RD
  6244.     //|  mov L:RB, L:CARG1d
  6245.     //|.else
  6246.     //|  mov ARG2, TAB:RB
  6247.     //|  mov L:RB, SAVE_L
  6248.     //|  mov L:RB->base, BASE
  6249.     //|  mov ARG3, RD
  6250.     //|  mov ARG1, L:RB
  6251.     //|.endif
  6252.     //|  mov SAVE_PC, PC
  6253.     //|  call extern lj_tab_reasize        // (lua_State *L, GCtab *t, int nasize)
  6254.     //|  mov BASE, L:RB->base
  6255.     //|  movzx RA, PC_RA                        // Restore RA.
  6256.     //|  jmp <1                                // Retry.
  6257.     //|
  6258.     //|7:  // Possible table write barrier for any value. Skip valiswhite check.
  6259.     //|  barrierback TAB:RB, RD
  6260.     dasm_put(Dst, 12812, Dt6(->marked), LJ_GC_BLACK, Dt6(->asize), Dt6(->array), Dt1(->base), Dt1(->base));
  6261. #line 4600 "vm_x86.dasc"
  6262.     //|  jmp <2
  6263.     dasm_put(Dst, 12962, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
  6264. #line 4601 "vm_x86.dasc"
  6265.     break;

  6266.   /* -- Calls and vararg handling ----------------------------------------- */

  6267.   case BC_CALL: case BC_CALLM:
  6268.     //|  ins_A_C        // RA = base, (RB = nresults+1,) RC = nargs+1 | extra_nargs
  6269.     dasm_put(Dst, 10040);
  6270. #line 4607 "vm_x86.dasc"
  6271.     if (op == BC_CALLM) {
  6272.       //|  add NARGS:RD, MULTRES
  6273.       dasm_put(Dst, 12982);
  6274. #line 4609 "vm_x86.dasc"
  6275.     }
  6276.     //|  cmp dword [BASE+RA*8+4], LJ_TFUNC
  6277.     //|  mov LFUNC:RB, [BASE+RA*8]
  6278.     //|  jne ->vmeta_call_ra
  6279.     //|  lea BASE, [BASE+RA*8+8]
  6280.     //|  ins_call
  6281.     dasm_put(Dst, 12987, LJ_TFUNC, Dt7(->pc));
  6282. #line 4615 "vm_x86.dasc"
  6283.     break;

  6284.   case BC_CALLMT:
  6285.     //|  ins_AD        // RA = base, RD = extra_nargs
  6286.     //|  add NARGS:RD, MULTRES
  6287.     //|  // Fall through. Assumes BC_CALLT follows and ins_AD is a no-op.
  6288.     dasm_put(Dst, 12982);
  6289. #line 4621 "vm_x86.dasc"
  6290.     break;
  6291.   case BC_CALLT:
  6292.     //|  ins_AD        // RA = base, RD = nargs+1
  6293.     //|  lea RA, [BASE+RA*8+8]
  6294.     //|  mov KBASE, BASE                        // Use KBASE for move + vmeta_call hint.
  6295.     //|  mov LFUNC:RB, [RA-8]
  6296.     //|  cmp dword [RA-4], LJ_TFUNC
  6297.     //|  jne ->vmeta_call
  6298.     //|->BC_CALLT_Z:
  6299.     //|  mov PC, [BASE-4]
  6300.     //|  test PC, FRAME_TYPE
  6301.     //|  jnz >7
  6302.     //|1:
  6303.     //|  mov [BASE-8], LFUNC:RB                // Copy function down, reloaded below.
  6304.     //|  mov MULTRES, NARGS:RD
  6305.     //|  sub NARGS:RD, 1
  6306.     //|  jz >3
  6307.     //|2:  // Move args down.
  6308.     //|.if X64
  6309.     //|  mov RBa, [RA]
  6310.     //|  add RA, 8
  6311.     //|  mov [KBASE], RBa
  6312.     //|.else
  6313.     //|  mov RB, [RA]
  6314.     //|  mov [KBASE], RB
  6315.     //|  mov RB, [RA+4]
  6316.     //|  add RA, 8
  6317.     //|  mov [KBASE+4], RB
  6318.     //|.endif
  6319.     //|  add KBASE, 8
  6320.     //|  sub NARGS:RD, 1
  6321.     //|  jnz <2
  6322.     //|
  6323.     //|  mov LFUNC:RB, [BASE-8]
  6324.     //|3:
  6325.     //|  mov NARGS:RD, MULTRES
  6326.     //|  cmp byte LFUNC:RB->ffid, 1        // (> FF_C) Calling a fast function?
  6327.     //|  ja >5
  6328.     //|4:
  6329.     //|  ins_callt
  6330.     //|
  6331.     //|5:  // Tailcall to a fast function.
  6332.     //|  test PC, FRAME_TYPE                // Lua frame below?
  6333.     dasm_put(Dst, 13030, LJ_TFUNC, FRAME_TYPE, Dt7(->ffid), Dt7(->pc));
  6334. #line 4664 "vm_x86.dasc"
  6335.     //|  jnz <4
  6336.     //|  movzx RA, PC_RA
  6337.     //|  not RAa
  6338.     //|  mov LFUNC:KBASE, [BASE+RA*8-8]        // Need to prepare KBASE.
  6339.     //|  mov KBASE, LFUNC:KBASE->pc
  6340.     //|  mov KBASE, [KBASE+PC2PROTO(k)]
  6341.     //|  jmp <4
  6342.     //|
  6343.     //|7:  // Tailcall from a vararg function.
  6344.     //|  sub PC, FRAME_VARG
  6345.     //|  test PC, FRAME_TYPEP
  6346.     //|  jnz >8                                // Vararg frame below?
  6347.     //|  sub BASE, PC                        // Need to relocate BASE/KBASE down.
  6348.     //|  mov KBASE, BASE
  6349.     //|  mov PC, [BASE-4]
  6350.     //|  jmp <1
  6351.     //|8:
  6352.     //|  add PC, FRAME_VARG
  6353.     //|  jmp <1
  6354.     dasm_put(Dst, 13148, FRAME_TYPE, Dt7(->pc), PC2PROTO(k), FRAME_VARG, FRAME_TYPEP, FRAME_VARG);
  6355. #line 4683 "vm_x86.dasc"
  6356.     break;

  6357.   case BC_ITERC:
  6358.     //|  ins_A        // RA = base, (RB = nresults+1,) RC = nargs+1 (2+1)
  6359.     //|  lea RA, [BASE+RA*8+8]                // fb = base+1
  6360.     //|.if X64
  6361.     //|  mov RBa, [RA-24]                        // Copy state. fb[0] = fb[-3].
  6362.     //|  mov RCa, [RA-16]                        // Copy control var. fb[1] = fb[-2].
  6363.     //|  mov [RA], RBa
  6364.     //|  mov [RA+8], RCa
  6365.     //|.else
  6366.     //|  mov RB, [RA-24]                        // Copy state. fb[0] = fb[-3].
  6367.     //|  mov RC, [RA-20]
  6368.     //|  mov [RA], RB
  6369.     //|  mov [RA+4], RC
  6370.     //|  mov RB, [RA-16]                        // Copy control var. fb[1] = fb[-2].
  6371.     //|  mov RC, [RA-12]
  6372.     //|  mov [RA+8], RB
  6373.     //|  mov [RA+12], RC
  6374.     //|.endif
  6375.     //|  mov LFUNC:RB, [RA-32]                // Copy callable. fb[-1] = fb[-4]
  6376.     //|  mov RC, [RA-28]
  6377.     //|  mov [RA-8], LFUNC:RB
  6378.     //|  mov [RA-4], RC
  6379.     //|  cmp RC, LJ_TFUNC                        // Handle like a regular 2-arg call.
  6380.     //|  mov NARGS:RD, 2+1
  6381.     //|  jne ->vmeta_call
  6382.     //|  mov BASE, RA
  6383.     //|  ins_call
  6384.     dasm_put(Dst, 13220, LJ_TFUNC, 2+1, Dt7(->pc));
  6385. #line 4712 "vm_x86.dasc"
  6386.     break;

  6387.   case BC_ITERN:
  6388.     //|  ins_A        // RA = base, (RB = nresults+1, RC = nargs+1 (2+1))
  6389.     //|.if JIT
  6390.     //|  // NYI: add hotloop, record BC_ITERN.
  6391.     //|.endif
  6392.     //|  mov TMP1, KBASE                        // Need two more free registers.
  6393.     //|  mov TMP2, DISPATCH
  6394.     //|  mov TAB:RB, [BASE+RA*8-16]
  6395.     //|  mov RC, [BASE+RA*8-8]                // Get index from control var.
  6396.     //|  mov DISPATCH, TAB:RB->asize
  6397.     //|  add PC, 4
  6398.     //|  mov KBASE, TAB:RB->array
  6399.     //|1:  // Traverse array part.
  6400.     //|  cmp RC, DISPATCH; jae >5                // Index points after array part?
  6401.     //|  cmp dword [KBASE+RC*8+4], LJ_TNIL; je >4
  6402.     //|.if DUALNUM
  6403.     //|  mov dword [BASE+RA*8+4], LJ_TISNUM
  6404.     //|  mov dword [BASE+RA*8], RC
  6405.     //|.else
  6406.     //|  cvtsi2sd xmm0, RC
  6407.     //|.endif
  6408.     //|  // Copy array slot to returned value.
  6409.     //|.if X64
  6410.     //|  mov RBa, [KBASE+RC*8]
  6411.     //|  mov [BASE+RA*8+8], RBa
  6412.     //|.else
  6413.     //|  mov RB, [KBASE+RC*8+4]
  6414.     //|  mov [BASE+RA*8+12], RB
  6415.     //|  mov RB, [KBASE+RC*8]
  6416.     //|  mov [BASE+RA*8+8], RB
  6417.     //|.endif
  6418.     //|  add RC, 1
  6419.     //|  // Return array index as a numeric key.
  6420.     //|.if DUALNUM
  6421.     //|  // See above.
  6422.     //|.else
  6423.     //|  movsd qword [BASE+RA*8], xmm0
  6424.     //|.endif
  6425.     //|  mov [BASE+RA*8-8], RC                // Update control var.
  6426.     //|2:
  6427.     //|  movzx RD, PC_RD                        // Get target from ITERL.
  6428.     //|  branchPC RD
  6429.     //|3:
  6430.     //|  mov DISPATCH, TMP2
  6431.     //|  mov KBASE, TMP1
  6432.     //|  ins_next
  6433.     //|
  6434.     //|4:  // Skip holes in array part.
  6435.     //|  add RC, 1
  6436.     //|  jmp <1
  6437.     //|
  6438.     //|5:  // Traverse hash part.
  6439.     //|  sub RC, DISPATCH
  6440.     //|6:
  6441.     //|  cmp RC, TAB:RB->hmask; ja <3        // End of iteration? Branch to ITERL+1.
  6442.     //|  imul KBASE, RC, #NODE
  6443.     dasm_put(Dst, 13292, Dt6(->asize), Dt6(->array), LJ_TNIL, LJ_TISNUM, -BCBIAS_J*4, Dt6(->hmask));
  6444. #line 4770 "vm_x86.dasc"
  6445.     //|  add NODE:KBASE, TAB:RB->node
  6446.     //|  cmp dword NODE:KBASE->val.it, LJ_TNIL; je >7
  6447.     //|  lea DISPATCH, [RC+DISPATCH+1]
  6448.     //|  // Copy key and value from hash slot.
  6449.     //|.if X64
  6450.     //|  mov RBa, NODE:KBASE->key
  6451.     //|  mov RCa, NODE:KBASE->val
  6452.     //|  mov [BASE+RA*8], RBa
  6453.     //|  mov [BASE+RA*8+8], RCa
  6454.     //|.else
  6455.     //|  mov RB, NODE:KBASE->key.gcr
  6456.     //|  mov RC, NODE:KBASE->key.it
  6457.     //|  mov [BASE+RA*8], RB
  6458.     //|  mov [BASE+RA*8+4], RC
  6459.     //|  mov RB, NODE:KBASE->val.gcr
  6460.     //|  mov RC, NODE:KBASE->val.it
  6461.     //|  mov [BASE+RA*8+8], RB
  6462.     //|  mov [BASE+RA*8+12], RC
  6463.     //|.endif
  6464.     //|  mov [BASE+RA*8-8], DISPATCH
  6465.     //|  jmp <2
  6466.     //|
  6467.     //|7:  // Skip holes in hash part.
  6468.     //|  add RC, 1
  6469.     //|  jmp <6
  6470.     dasm_put(Dst, 13436, sizeof(Node), Dt6(->node), DtB(->val.it), LJ_TNIL, DtB(->key), DtB(->val));
  6471. #line 4795 "vm_x86.dasc"
  6472.     break;

  6473.   case BC_ISNEXT:
  6474.     //|  ins_AD        // RA = base, RD = target (points to ITERN)
  6475.     //|  cmp dword [BASE+RA*8-20], LJ_TFUNC; jne >5
  6476.     //|  mov CFUNC:RB, [BASE+RA*8-24]
  6477.     //|  cmp dword [BASE+RA*8-12], LJ_TTAB; jne >5
  6478.     //|  cmp dword [BASE+RA*8-4], LJ_TNIL; jne >5
  6479.     //|  cmp byte CFUNC:RB->ffid, FF_next_N; jne >5
  6480.     //|  branchPC RD
  6481.     //|  mov dword [BASE+RA*8-8], 0        // Initialize control var.
  6482.     //|  mov dword [BASE+RA*8-4], 0xfffe7fff
  6483.     //|1:
  6484.     //|  ins_next
  6485.     //|5:  // Despecialize bytecode if any of the checks fail.
  6486.     //|  mov PC_OP, BC_JMP
  6487.     //|  branchPC RD
  6488.     //|  mov byte [PC], BC_ITERC
  6489.     //|  jmp <1
  6490.     dasm_put(Dst, 13496, LJ_TFUNC, LJ_TTAB, LJ_TNIL, Dt8(->ffid), FF_next_N, -BCBIAS_J*4, BC_JMP, -BCBIAS_J*4, BC_ITERC);
  6491. #line 4814 "vm_x86.dasc"
  6492.     break;

  6493.   case BC_VARG:
  6494.     //|  ins_ABC        // RA = base, RB = nresults+1, RC = numparams
  6495.     //|  mov TMP1, KBASE                        // Need one more free register.
  6496.     //|  lea KBASE, [BASE+RC*8+(8+FRAME_VARG)]
  6497.     //|  lea RA, [BASE+RA*8]
  6498.     //|  sub KBASE, [BASE-4]
  6499.     //|  // Note: KBASE may now be even _above_ BASE if nargs was < numparams.
  6500.     //|  test RB, RB
  6501.     //|  jz >5                                // Copy all varargs?
  6502.     //|  lea RB, [RA+RB*8-8]
  6503.     //|  cmp KBASE, BASE                        // No vararg slots?
  6504.     //|  jnb >2
  6505.     //|1:  // Copy vararg slots to destination slots.
  6506.     //|.if X64
  6507.     //|  mov RCa, [KBASE-8]
  6508.     //|  add KBASE, 8
  6509.     //|  mov [RA], RCa
  6510.     //|.else
  6511.     //|  mov RC, [KBASE-8]
  6512.     //|  mov [RA], RC
  6513.     //|  mov RC, [KBASE-4]
  6514.     //|  add KBASE, 8
  6515.     //|  mov [RA+4], RC
  6516.     //|.endif
  6517.     //|  add RA, 8
  6518.     //|  cmp RA, RB                        // All destination slots filled?
  6519.     //|  jnb >3
  6520.     //|  cmp KBASE, BASE                        // No more vararg slots?
  6521.     //|  jb <1
  6522.     //|2:  // Fill up remainder with nil.
  6523.     //|  mov dword [RA+4], LJ_TNIL
  6524.     //|  add RA, 8
  6525.     //|  cmp RA, RB
  6526.     //|  jb <2
  6527.     //|3:
  6528.     //|  mov KBASE, TMP1
  6529.     //|  ins_next
  6530.     //|
  6531.     //|5:  // Copy all varargs.
  6532.     //|  mov MULTRES, 1                        // MULTRES = 0+1
  6533.     //|  mov RC, BASE
  6534.     //|  sub RC, KBASE
  6535.     //|  jbe <3                                // No vararg slots?
  6536.     //|  mov RB, RC
  6537.     //|  shr RB, 3
  6538.     //|  add RB, 1
  6539.     //|  mov MULTRES, RB                        // MULTRES = #varargs+1
  6540.     //|  mov L:RB, SAVE_L
  6541.     //|  add RC, RA
  6542.     //|  cmp RC, L:RB->maxstack
  6543.     //|  ja >7                                // Need to grow stack?
  6544.     //|6:  // Copy all vararg slots.
  6545.     //|.if X64
  6546.     //|  mov RCa, [KBASE-8]
  6547.     dasm_put(Dst, 13609, (8+FRAME_VARG), LJ_TNIL, Dt1(->maxstack));
  6548. #line 4870 "vm_x86.dasc"
  6549.     //|  add KBASE, 8
  6550.     //|  mov [RA], RCa
  6551.     //|.else
  6552.     //|  mov RC, [KBASE-8]
  6553.     //|  mov [RA], RC
  6554.     //|  mov RC, [KBASE-4]
  6555.     //|  add KBASE, 8
  6556.     //|  mov [RA+4], RC
  6557.     //|.endif
  6558.     //|  add RA, 8
  6559.     //|  cmp KBASE, BASE                        // No more vararg slots?
  6560.     //|  jb <6
  6561.     //|  jmp <3
  6562.     //|
  6563.     //|7:  // Grow stack for varargs.
  6564.     //|  mov L:RB->base, BASE
  6565.     //|  mov L:RB->top, RA
  6566.     //|  mov SAVE_PC, PC
  6567.     //|  sub KBASE, BASE                        // Need delta, because BASE may change.
  6568.     //|  mov FCARG2, MULTRES
  6569.     //|  sub FCARG2, 1
  6570.     //|  mov FCARG1, L:RB
  6571.     //|  call extern lj_state_growstack@8        // (lua_State *L, int n)
  6572.     //|  mov BASE, L:RB->base
  6573.     //|  mov RA, L:RB->top
  6574.     //|  add KBASE, BASE
  6575.     //|  jmp <6
  6576.     dasm_put(Dst, 13776, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
  6577. #line 4897 "vm_x86.dasc"
  6578.     break;

  6579.   /* -- Returns ----------------------------------------------------------- */

  6580.   case BC_RETM:
  6581.     //|  ins_AD        // RA = results, RD = extra_nresults
  6582.     //|  add RD, MULTRES                        // MULTRES >=1, so RD >=1.
  6583.     //|  // Fall through. Assumes BC_RET follows and ins_AD is a no-op.
  6584.     dasm_put(Dst, 12982);
  6585. #line 4905 "vm_x86.dasc"
  6586.     break;

  6587.   case BC_RET: case BC_RET0: case BC_RET1:
  6588.     //|  ins_AD        // RA = results, RD = nresults+1
  6589.     if (op != BC_RET0) {
  6590.       //|  shl RA, 3
  6591.       dasm_put(Dst, 13846);
  6592. #line 4911 "vm_x86.dasc"
  6593.     }
  6594.     //|1:
  6595.     //|  mov PC, [BASE-4]
  6596.     //|  mov MULTRES, RD                        // Save nresults+1.
  6597.     //|  test PC, FRAME_TYPE                // Check frame type marker.
  6598.     //|  jnz >7                                // Not returning to a fixarg Lua func?
  6599.     dasm_put(Dst, 13850, FRAME_TYPE);
  6600. #line 4917 "vm_x86.dasc"
  6601.     switch (op) {
  6602.     case BC_RET:
  6603.       //|->BC_RET_Z:
  6604.       //|  mov KBASE, BASE                // Use KBASE for result move.
  6605.       //|  sub RD, 1
  6606.       //|  jz >3
  6607.       //|2:  // Move results down.
  6608.       //|.if X64
  6609.       //|  mov RBa, [KBASE+RA]
  6610.       //|  mov [KBASE-8], RBa
  6611.       //|.else
  6612.       //|  mov RB, [KBASE+RA]
  6613.       //|  mov [KBASE-8], RB
  6614.       //|  mov RB, [KBASE+RA+4]
  6615.       //|  mov [KBASE-4], RB
  6616.       //|.endif
  6617.       //|  add KBASE, 8
  6618.       //|  sub RD, 1
  6619.       //|  jnz <2
  6620.       //|3:
  6621.       //|  mov RD, MULTRES                // Note: MULTRES may be >255.
  6622.       //|  movzx RB, PC_RB                // So cannot compare with RDL!
  6623.       //|5:
  6624.       //|  cmp RB, RD                        // More results expected?
  6625.       //|  ja >6
  6626.       dasm_put(Dst, 13869);
  6627. #line 4942 "vm_x86.dasc"
  6628.       break;
  6629.     case BC_RET1:
  6630.       //|.if X64
  6631.       //|  mov RBa, [BASE+RA]
  6632.       //|  mov [BASE-8], RBa
  6633.       //|.else
  6634.       //|  mov RB, [BASE+RA+4]
  6635.       //|  mov [BASE-4], RB
  6636.       //|  mov RB, [BASE+RA]
  6637.       //|  mov [BASE-8], RB
  6638.       //|.endif
  6639.       dasm_put(Dst, 13923);
  6640. #line 4953 "vm_x86.dasc"
  6641.       /* fallthrough */
  6642.     case BC_RET0:
  6643.       //|5:
  6644.       //|  cmp PC_RB, RDL                        // More results expected?
  6645.       //|  ja >6
  6646.       dasm_put(Dst, 13933);
  6647. #line 4958 "vm_x86.dasc"
  6648.     default:
  6649.       break;
  6650.     }
  6651.     //|  movzx RA, PC_RA
  6652.     //|  not RAa                                // Note: ~RA = -(RA+1)
  6653.     //|  lea BASE, [BASE+RA*8]                // base = base - (RA+1)*8
  6654.     //|  mov LFUNC:KBASE, [BASE-8]
  6655.     //|  mov KBASE, LFUNC:KBASE->pc
  6656.     //|  mov KBASE, [KBASE+PC2PROTO(k)]
  6657.     //|  ins_next
  6658.     //|
  6659.     //|6:  // Fill up results with nil.
  6660.     dasm_put(Dst, 13944, Dt7(->pc), PC2PROTO(k));
  6661. #line 4970 "vm_x86.dasc"
  6662.     if (op == BC_RET) {
  6663.       //|  mov dword [KBASE-4], LJ_TNIL        // Note: relies on shifted base.
  6664.       //|  add KBASE, 8
  6665.       dasm_put(Dst, 13992, LJ_TNIL);
  6666. #line 4973 "vm_x86.dasc"
  6667.     } else {
  6668.       //|  mov dword [BASE+RD*8-12], LJ_TNIL
  6669.       dasm_put(Dst, 14003, LJ_TNIL);
  6670. #line 4975 "vm_x86.dasc"
  6671.     }
  6672.     //|  add RD, 1
  6673.     //|  jmp <5
  6674.     //|
  6675.     //|7:  // Non-standard return case.
  6676.     //|  lea RB, [PC-FRAME_VARG]
  6677.     //|  test RB, FRAME_TYPEP
  6678.     //|  jnz ->vm_return
  6679.     //|  // Return from vararg function: relocate BASE down and RA up.
  6680.     //|  sub BASE, RB
  6681.     dasm_put(Dst, 14010, -FRAME_VARG, FRAME_TYPEP);
  6682. #line 4985 "vm_x86.dasc"
  6683.     if (op != BC_RET0) {
  6684.       //|  add RA, RB
  6685.       dasm_put(Dst, 14034);
  6686. #line 4987 "vm_x86.dasc"
  6687.     }
  6688.     //|  jmp <1
  6689.     dasm_put(Dst, 10015);
  6690. #line 4989 "vm_x86.dasc"
  6691.     break;

  6692.   /* -- Loops and branches ------------------------------------------------ */

  6693.   //|.define FOR_IDX,  [RA];    .define FOR_TIDX,  dword [RA+4]
  6694.   //|.define FOR_STOP, [RA+8];  .define FOR_TSTOP, dword [RA+12]
  6695.   //|.define FOR_STEP, [RA+16]; .define FOR_TSTEP, dword [RA+20]
  6696.   //|.define FOR_EXT,  [RA+24]; .define FOR_TEXT,  dword [RA+28]

  6697.   case BC_FORL:
  6698.     //|.if JIT
  6699.     //|  hotloop RB
  6700.     //|.endif
  6701.     //| // Fall through. Assumes BC_IFORL follows and ins_AJ is a no-op.
  6702.     dasm_put(Dst, 14038, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
  6703. #line 5003 "vm_x86.dasc"
  6704.     break;

  6705.   case BC_JFORI:
  6706.   case BC_JFORL:
  6707. #if !LJ_HASJIT
  6708.     break;
  6709. #endif
  6710.   case BC_FORI:
  6711.   case BC_IFORL:
  6712.     vk = (op == BC_IFORL || op == BC_JFORL);
  6713.     //|  ins_AJ        // RA = base, RD = target (after end of loop or start of loop)
  6714.     //|  lea RA, [BASE+RA*8]
  6715.     dasm_put(Dst, 14059);
  6716. #line 5015 "vm_x86.dasc"
  6717.     if (LJ_DUALNUM) {
  6718.       //|  cmp FOR_TIDX, LJ_TISNUM; jne >9
  6719.       dasm_put(Dst, 14063, LJ_TISNUM);
  6720. #line 5017 "vm_x86.dasc"
  6721.       if (!vk) {
  6722.         //|  cmp FOR_TSTOP, LJ_TISNUM; jne ->vmeta_for
  6723.         //|  cmp FOR_TSTEP, LJ_TISNUM; jne ->vmeta_for
  6724.         //|  mov RB, dword FOR_IDX
  6725.         //|  cmp dword FOR_STEP, 0; jl >5
  6726.         dasm_put(Dst, 14073, LJ_TISNUM, LJ_TISNUM);
  6727. #line 5022 "vm_x86.dasc"
  6728.       } else {
  6729. #ifdef LUA_USE_ASSERT
  6730.         //|  cmp FOR_TSTOP, LJ_TISNUM; jne ->assert_bad_for_arg_type
  6731.         //|  cmp FOR_TSTEP, LJ_TISNUM; jne ->assert_bad_for_arg_type
  6732.         dasm_put(Dst, 14102, LJ_TISNUM, LJ_TISNUM);
  6733. #line 5026 "vm_x86.dasc"
  6734. #endif
  6735.         //|  mov RB, dword FOR_STEP
  6736.         //|  test RB, RB; js >5
  6737.         //|  add RB, dword FOR_IDX; jo >1
  6738.         //|  mov dword FOR_IDX, RB
  6739.         dasm_put(Dst, 14121);
  6740. #line 5031 "vm_x86.dasc"
  6741.       }
  6742.       //|  cmp RB, dword FOR_STOP
  6743.       //|  mov FOR_TEXT, LJ_TISNUM
  6744.       //|  mov dword FOR_EXT, RB
  6745.       dasm_put(Dst, 14140, LJ_TISNUM);
  6746. #line 5035 "vm_x86.dasc"
  6747.       if (op == BC_FORI) {
  6748.         //|  jle >7
  6749.         //|1:
  6750.         //|6:
  6751.         //|  branchPC RD
  6752.         dasm_put(Dst, 14151, -BCBIAS_J*4);
  6753. #line 5040 "vm_x86.dasc"
  6754.       } else if (op == BC_JFORI) {
  6755.         //|  branchPC RD
  6756.         //|  movzx RD, PC_RD
  6757.         //|  jle =>BC_JLOOP
  6758.         //|1:
  6759.         //|6:
  6760.         dasm_put(Dst, 14165, -BCBIAS_J*4, BC_JLOOP);
  6761. #line 5046 "vm_x86.dasc"
  6762.       } else if (op == BC_IFORL) {
  6763.         //|  jg >7
  6764.         //|6:
  6765.         //|  branchPC RD
  6766.         //|1:
  6767.         dasm_put(Dst, 14183, -BCBIAS_J*4);
  6768. #line 5051 "vm_x86.dasc"
  6769.       } else {
  6770.         //|  jle =>BC_JLOOP
  6771.         //|1:
  6772.         //|6:
  6773.         dasm_put(Dst, 14175, BC_JLOOP);
  6774. #line 5055 "vm_x86.dasc"
  6775.       }
  6776.       //|7:
  6777.       //|  ins_next
  6778.       //|
  6779.       //|5:  // Invert check for negative step.
  6780.       dasm_put(Dst, 14197);
  6781. #line 5060 "vm_x86.dasc"
  6782.       if (vk) {
  6783.         //|  add RB, dword FOR_IDX; jo <1
  6784.         //|  mov dword FOR_IDX, RB
  6785.         dasm_put(Dst, 14222);
  6786. #line 5063 "vm_x86.dasc"
  6787.       }
  6788.       //|  cmp RB, dword FOR_STOP
  6789.       //|  mov FOR_TEXT, LJ_TISNUM
  6790.       //|  mov dword FOR_EXT, RB
  6791.       dasm_put(Dst, 14140, LJ_TISNUM);
  6792. #line 5067 "vm_x86.dasc"
  6793.       if (op == BC_FORI) {
  6794.         //|  jge <7
  6795.         dasm_put(Dst, 14231);
  6796. #line 5069 "vm_x86.dasc"
  6797.       } else if (op == BC_JFORI) {
  6798.         //|  branchPC RD
  6799.         //|  movzx RD, PC_RD
  6800.         //|  jge =>BC_JLOOP
  6801.         dasm_put(Dst, 14236, -BCBIAS_J*4, BC_JLOOP);
  6802. #line 5073 "vm_x86.dasc"
  6803.       } else if (op == BC_IFORL) {
  6804.         //|  jl <7
  6805.         dasm_put(Dst, 14250);
  6806. #line 5075 "vm_x86.dasc"
  6807.       } else {
  6808.         //|  jge =>BC_JLOOP
  6809.         dasm_put(Dst, 14246, BC_JLOOP);
  6810. #line 5077 "vm_x86.dasc"
  6811.       }
  6812.       //|  jmp <6
  6813.       //|9:  // Fallback to FP variant.
  6814.       dasm_put(Dst, 14255);
  6815. #line 5080 "vm_x86.dasc"
  6816.     } else if (!vk) {
  6817.       //|  cmp FOR_TIDX, LJ_TISNUM
  6818.       dasm_put(Dst, 14262, LJ_TISNUM);
  6819. #line 5082 "vm_x86.dasc"
  6820.     }
  6821.     if (!vk) {
  6822.       //|  jae ->vmeta_for
  6823.       //|  cmp FOR_TSTOP, LJ_TISNUM; jae ->vmeta_for
  6824.       dasm_put(Dst, 14268, LJ_TISNUM);
  6825. #line 5086 "vm_x86.dasc"
  6826.     } else {
  6827. #ifdef LUA_USE_ASSERT
  6828.       //|  cmp FOR_TSTOP, LJ_TISNUM; jae ->assert_bad_for_arg_type
  6829.       //|  cmp FOR_TSTEP, LJ_TISNUM; jae ->assert_bad_for_arg_type
  6830.       dasm_put(Dst, 14282, LJ_TISNUM, LJ_TISNUM);
  6831. #line 5090 "vm_x86.dasc"
  6832. #endif
  6833.     }
  6834.     //|  mov RB, FOR_TSTEP                // Load type/hiword of for step.
  6835.     dasm_put(Dst, 14301);
  6836. #line 5093 "vm_x86.dasc"
  6837.     if (!vk) {
  6838.       //|  cmp RB, LJ_TISNUM; jae ->vmeta_for
  6839.       dasm_put(Dst, 14305, LJ_TISNUM);
  6840. #line 5095 "vm_x86.dasc"
  6841.     }
  6842.     //|  movsd xmm0, qword FOR_IDX
  6843.     //|  movsd xmm1, qword FOR_STOP
  6844.     dasm_put(Dst, 14314);
  6845. #line 5098 "vm_x86.dasc"
  6846.     if (vk) {
  6847.       //|  addsd xmm0, qword FOR_STEP
  6848.       //|  movsd qword FOR_IDX, xmm0
  6849.       //|  test RB, RB; js >3
  6850.       dasm_put(Dst, 14326);
  6851. #line 5102 "vm_x86.dasc"
  6852.     } else {
  6853.       //|  jl >3
  6854.       dasm_put(Dst, 14345);
  6855. #line 5104 "vm_x86.dasc"
  6856.     }
  6857.     //|  ucomisd xmm1, xmm0
  6858.     //|1:
  6859.     //|  movsd qword FOR_EXT, xmm0
  6860.     dasm_put(Dst, 14350);
  6861. #line 5108 "vm_x86.dasc"
  6862.     if (op == BC_FORI) {
  6863.       //|.if DUALNUM
  6864.       //|  jnb <7
  6865.       //|.else
  6866.       //|  jnb >2
  6867.       //|  branchPC RD
  6868.       //|.endif
  6869.       dasm_put(Dst, 14363);
  6870. #line 5115 "vm_x86.dasc"
  6871.     } else if (op == BC_JFORI) {
  6872.       //|  branchPC RD
  6873.       //|  movzx RD, PC_RD
  6874.       //|  jnb =>BC_JLOOP
  6875.       dasm_put(Dst, 14368, -BCBIAS_J*4, BC_JLOOP);
  6876. #line 5119 "vm_x86.dasc"
  6877.     } else if (op == BC_IFORL) {
  6878.       //|.if DUALNUM
  6879.       //|  jb <7
  6880.       //|.else
  6881.       //|  jb >2
  6882.       //|  branchPC RD
  6883.       //|.endif
  6884.       dasm_put(Dst, 14382);
  6885. #line 5126 "vm_x86.dasc"
  6886.     } else {
  6887.       //|  jnb =>BC_JLOOP
  6888.       dasm_put(Dst, 14378, BC_JLOOP);
  6889. #line 5128 "vm_x86.dasc"
  6890.     }
  6891.     //|.if DUALNUM
  6892.     //|  jmp <6
  6893.     //|.else
  6894.     //|2:
  6895.     //|  ins_next
  6896.     //|.endif
  6897.     //|
  6898.     //|3:  // Invert comparison if step is negative.
  6899.     //|  ucomisd xmm0, xmm1
  6900.     //|  jmp <1
  6901.     dasm_put(Dst, 14387);
  6902. #line 5139 "vm_x86.dasc"
  6903.     break;

  6904.   case BC_ITERL:
  6905.     //|.if JIT
  6906.     //|  hotloop RB
  6907.     //|.endif
  6908.     //| // Fall through. Assumes BC_IITERL follows and ins_AJ is a no-op.
  6909.     dasm_put(Dst, 14038, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
  6910. #line 5146 "vm_x86.dasc"
  6911.     break;

  6912.   case BC_JITERL:
  6913. #if !LJ_HASJIT
  6914.     break;
  6915. #endif
  6916.   case BC_IITERL:
  6917.     //|  ins_AJ        // RA = base, RD = target
  6918.     //|  lea RA, [BASE+RA*8]
  6919.     //|  mov RB, [RA+4]
  6920.     //|  cmp RB, LJ_TNIL; je >1                // Stop if iterator returned nil.
  6921.     dasm_put(Dst, 14402, LJ_TNIL);
  6922. #line 5157 "vm_x86.dasc"
  6923.     if (op == BC_JITERL) {
  6924.       //|  mov [RA-4], RB
  6925.       //|  mov RB, [RA]
  6926.       //|  mov [RA-8], RB
  6927.       //|  jmp =>BC_JLOOP
  6928.       dasm_put(Dst, 14417, BC_JLOOP);
  6929. #line 5162 "vm_x86.dasc"
  6930.     } else {
  6931.       //|  branchPC RD                        // Otherwise save control var + branch.
  6932.       //|  mov RD, [RA]
  6933.       //|  mov [RA-4], RB
  6934.       //|  mov [RA-8], RD
  6935.       dasm_put(Dst, 14431, -BCBIAS_J*4);
  6936. #line 5167 "vm_x86.dasc"
  6937.     }
  6938.     //|1:
  6939.     //|  ins_next
  6940.     dasm_put(Dst, 9668);
  6941. #line 5170 "vm_x86.dasc"
  6942.     break;

  6943.   case BC_LOOP:
  6944.     //|  ins_A        // RA = base, RD = target (loop extent)
  6945.     //|  // Note: RA/RD is only used by trace recorder to determine scope/extent
  6946.     //|  // This opcode does NOT jump, it's only purpose is to detect a hot loop.
  6947.     //|.if JIT
  6948.     //|  hotloop RB
  6949.     //|.endif
  6950.     //| // Fall through. Assumes BC_ILOOP follows and ins_A is a no-op.
  6951.     dasm_put(Dst, 14038, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
  6952. #line 5180 "vm_x86.dasc"
  6953.     break;

  6954.   case BC_ILOOP:
  6955.     //|  ins_A        // RA = base, RD = target (loop extent)
  6956.     //|  ins_next
  6957.     dasm_put(Dst, 9224);
  6958. #line 5185 "vm_x86.dasc"
  6959.     break;

  6960.   case BC_JLOOP:
  6961.     //|.if JIT
  6962.     //|  ins_AD        // RA = base (ignored), RD = traceno
  6963. #ifdef LUA_USE_TRACE_LOGS
  6964.     //|.if X64
  6965.     //|  mov L:RB, SAVE_L
  6966.     //|  mov L:RB->base, BASE  // Save BASE
  6967.     //|  mov TMP1, RD     // Save RD
  6968.     //|  mov CARG3d, PC  // CARG3d == BASE
  6969.     //|  mov FCARG2, RD
  6970.     //|  mov FCARG1, RB
  6971.     //|  call extern lj_log_trace_entry@8
  6972.     //|  mov RD, TMP1
  6973.     //|  mov BASE, L:RB->base
  6974.     //|.endif
  6975.     dasm_put(Dst, 14447, Dt1(->base), Dt1(->base));
  6976. #line 5202 "vm_x86.dasc"
  6977. #endif
  6978.     //|  mov RA, [DISPATCH+DISPATCH_J(trace)]
  6979.     //|  mov TRACE:RD, [RA+RD*4]
  6980.     //|  mov RDa, TRACE:RD->mcode
  6981.     //|  mov L:RB, SAVE_L
  6982.     //|  mov [DISPATCH+DISPATCH_GL(jit_base)], BASE
  6983.     //|  mov [DISPATCH+DISPATCH_GL(tmpbuf.L)], L:RB
  6984.     //|  // Save additional callee-save registers only used in compiled code.
  6985.     //|.if X64WIN
  6986.     //|  mov TMPQ, r12
  6987.     //|  mov TMPa, r13
  6988.     //|  mov CSAVE_4, r14
  6989.     //|  mov CSAVE_3, r15
  6990.     //|  mov RAa, rsp
  6991.     //|  sub rsp, 9*16+4*8
  6992.     //|  movdqa [RAa], xmm6
  6993.     //|  movdqa [RAa-1*16], xmm7
  6994.     //|  movdqa [RAa-2*16], xmm8
  6995.     //|  movdqa [RAa-3*16], xmm9
  6996.     //|  movdqa [RAa-4*16], xmm10
  6997.     //|  movdqa [RAa-5*16], xmm11
  6998.     //|  movdqa [RAa-6*16], xmm12
  6999.     //|  movdqa [RAa-7*16], xmm13
  7000.     //|  movdqa [RAa-8*16], xmm14
  7001.     //|  movdqa [RAa-9*16], xmm15
  7002.     //|.elif X64
  7003.     //|  mov TMPQ, r12
  7004.     //|  mov TMPa, r13
  7005.     //|  sub rsp, 16
  7006.     //|.endif
  7007.     //|  jmp RDa
  7008.     //|.endif
  7009.     dasm_put(Dst, 14475, DISPATCH_J(trace), DtD(->mcode), DISPATCH_GL(jit_base), DISPATCH_GL(tmpbuf.L));
  7010. #line 5234 "vm_x86.dasc"
  7011.     break;

  7012.   case BC_JMP:
  7013.     //|  ins_AJ        // RA = unused, RD = target
  7014.     //|  branchPC RD
  7015.     //|  ins_next
  7016.     dasm_put(Dst, 14516, -BCBIAS_J*4);
  7017. #line 5240 "vm_x86.dasc"
  7018.     break;

  7019.   /* -- Function headers -------------------------------------------------- */

  7020.    /*
  7021.    ** Reminder: A function may be called with func/args above L->maxstack,
  7022.    ** i.e. occupying EXTRA_STACK slots. And vmeta_call may add one extra slot,
  7023.    ** too. This means all FUNC* ops (including fast functions) must check
  7024.    ** for stack overflow _before_ adding more slots!
  7025.    */

  7026.   case BC_FUNCF:
  7027.     //|.if JIT
  7028.     //|  hotcall RB
  7029.     //|.endif
  7030.     dasm_put(Dst, 14542, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_CALL);
  7031. #line 5255 "vm_x86.dasc"
  7032.   case BC_FUNCV:  /* NYI: compiled vararg functions. */
  7033.     //| // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow and ins_AD is a no-op.
  7034.     break;

  7035.   case BC_JFUNCF:
  7036. #if !LJ_HASJIT
  7037.     break;
  7038. #endif
  7039.   case BC_IFUNCF:
  7040.     //|  ins_AD  // BASE = new base, RA = framesize, RD = nargs+1
  7041.     //|  mov KBASE, [PC-4+PC2PROTO(k)]
  7042.     //|  mov L:RB, SAVE_L
  7043.     //|  lea RA, [BASE+RA*8]                // Top of frame.
  7044.     //|  cmp RA, L:RB->maxstack
  7045.     //|  ja ->vm_growstack_f
  7046.     //|  movzx RA, byte [PC-4+PC2PROTO(numparams)]
  7047.     //|  cmp NARGS:RD, RA                        // Check for missing parameters.
  7048.     //|  jbe >3
  7049.     //|2:
  7050.     dasm_put(Dst, 14563, -4+PC2PROTO(k), Dt1(->maxstack), -4+PC2PROTO(numparams));
  7051. #line 5274 "vm_x86.dasc"
  7052.     if (op == BC_JFUNCF) {
  7053.       //|  movzx RD, PC_RD
  7054.       //|  jmp =>BC_JLOOP
  7055.       dasm_put(Dst, 14594, BC_JLOOP);
  7056. #line 5277 "vm_x86.dasc"
  7057.     } else {
  7058.       //|  ins_next
  7059.       dasm_put(Dst, 9224);
  7060. #line 5279 "vm_x86.dasc"
  7061.     }
  7062.     //|
  7063.     //|3:  // Clear missing parameters.
  7064.     //|  mov dword [BASE+NARGS:RD*8-4], LJ_TNIL
  7065.     //|  add NARGS:RD, 1
  7066.     //|  cmp NARGS:RD, RA
  7067.     //|  jbe <3
  7068.     //|  jmp <2
  7069.     dasm_put(Dst, 14603, LJ_TNIL);
  7070. #line 5287 "vm_x86.dasc"
  7071.     break;

  7072.   case BC_JFUNCV:
  7073. #if !LJ_HASJIT
  7074.     break;
  7075. #endif
  7076.     //| int3  // NYI: compiled vararg functions
  7077.     dasm_put(Dst, 8467);
  7078. #line 5294 "vm_x86.dasc"
  7079.     break/* NYI: compiled vararg functions. */

  7080.   case BC_IFUNCV:
  7081.     //|  ins_AD  // BASE = new base, RA = framesize, RD = nargs+1
  7082.     //|  lea RB, [NARGS:RD*8+FRAME_VARG]
  7083.     //|  lea RD, [BASE+NARGS:RD*8]
  7084.     //|  mov LFUNC:KBASE, [BASE-8]
  7085.     //|  mov [RD-4], RB                        // Store delta + FRAME_VARG.
  7086.     //|  mov [RD-8], LFUNC:KBASE                // Store copy of LFUNC.
  7087.     //|  mov L:RB, SAVE_L
  7088.     //|  lea RA, [RD+RA*8]
  7089.     //|  cmp RA, L:RB->maxstack
  7090.     //|  ja ->vm_growstack_v                // Need to grow stack.
  7091.     //|  mov RA, BASE
  7092.     //|  mov BASE, RD
  7093.     //|  movzx RB, byte [PC-4+PC2PROTO(numparams)]
  7094.     //|  test RB, RB
  7095.     //|  jz >2
  7096.     //|1:  // Copy fixarg slots up to new frame.
  7097.     //|  add RA, 8
  7098.     //|  cmp RA, BASE
  7099.     //|  jnb >3                                // Less args than parameters?
  7100.     //|  mov KBASE, [RA-8]
  7101.     //|  mov [RD], KBASE
  7102.     //|  mov KBASE, [RA-4]
  7103.     //|  mov [RD+4], KBASE
  7104.     //|  add RD, 8
  7105.     //|  mov dword [RA-4], LJ_TNIL        // Clear old fixarg slot (help the GC).
  7106.     //|  sub RB, 1
  7107.     //|  jnz <1
  7108.     //|2:
  7109.     dasm_put(Dst, 14625, FRAME_VARG, Dt1(->maxstack), -4+PC2PROTO(numparams), LJ_TNIL);
  7110. #line 5325 "vm_x86.dasc"
  7111.     if (op == BC_JFUNCV) {
  7112.       //|  movzx RD, PC_RD
  7113.       //|  jmp =>BC_JLOOP
  7114.       dasm_put(Dst, 14594, BC_JLOOP);
  7115. #line 5328 "vm_x86.dasc"
  7116.     } else {
  7117.       //|  mov KBASE, [PC-4+PC2PROTO(k)]
  7118.       //|  ins_next
  7119.       dasm_put(Dst, 14722, -4+PC2PROTO(k));
  7120. #line 5331 "vm_x86.dasc"
  7121.     }
  7122.     //|
  7123.     //|3:  // Clear missing parameters.
  7124.     //|  mov dword [RD+4], LJ_TNIL
  7125.     //|  add RD, 8
  7126.     //|  sub RB, 1
  7127.     //|  jnz <3
  7128.     //|  jmp <2
  7129.     dasm_put(Dst, 14747, LJ_TNIL);
  7130. #line 5339 "vm_x86.dasc"
  7131.     break;

  7132.   case BC_FUNCC:
  7133.   case BC_FUNCCW:
  7134.     //|  ins_AD  // BASE = new base, RA = ins RA|RD (unused), RD = nargs+1
  7135.     //|  mov CFUNC:RB, [BASE-8]
  7136.     //|  mov KBASEa, CFUNC:RB->f
  7137.     //|  mov L:RB, SAVE_L
  7138.     //|  lea RD, [BASE+NARGS:RD*8-8]
  7139.     //|  mov L:RB->base, BASE
  7140.     //|  lea RA, [RD+8*LUA_MINSTACK]
  7141.     //|  cmp RA, L:RB->maxstack
  7142.     //|  mov L:RB->top, RD
  7143.     dasm_put(Dst, 14769, Dt8(->f), Dt1(->base), 8*LUA_MINSTACK, Dt1(->maxstack), Dt1(->top));
  7144. #line 5352 "vm_x86.dasc"
  7145.     if (op == BC_FUNCC) {
  7146.       //|.if X64
  7147.       //|  mov CARG1d, L:RB                        // Caveat: CARG1d may be RA.
  7148.       //|.else
  7149.       //|  mov ARG1, L:RB
  7150.       //|.endif
  7151.       dasm_put(Dst, 14799);
  7152. #line 5358 "vm_x86.dasc"
  7153.     } else {
  7154.       //|.if X64
  7155.       //|  mov CARG2, KBASEa
  7156.       //|  mov CARG1d, L:RB                        // Caveat: CARG1d may be RA.
  7157.       //|.else
  7158.       //|  mov ARG2, KBASEa
  7159.       //|  mov ARG1, L:RB
  7160.       //|.endif
  7161.       dasm_put(Dst, 14803);
  7162. #line 5366 "vm_x86.dasc"
  7163.     }
  7164.     //|  ja ->vm_growstack_c                // Need to grow stack.
  7165.     //|  set_vmstate C
  7166.     dasm_put(Dst, 14811, DISPATCH_GL(vmstate), ~LJ_VMST_C);
  7167. #line 5369 "vm_x86.dasc"
  7168.     if (op == BC_FUNCC) {
  7169.       //|  call KBASEa                        // (lua_State *L)
  7170.       dasm_put(Dst, 14821);
  7171. #line 5371 "vm_x86.dasc"
  7172.     } else {
  7173.       //|  // (lua_State *L, lua_CFunction f)
  7174.       //|  call aword [DISPATCH+DISPATCH_GL(wrapf)]
  7175.       dasm_put(Dst, 14826, DISPATCH_GL(wrapf));
  7176. #line 5374 "vm_x86.dasc"
  7177.     }
  7178.     //|  // nresults returned in eax (RD).
  7179.     //|  mov BASE, L:RB->base
  7180.     //|  mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
  7181.     //|  set_vmstate INTERP
  7182.     //|  lea RA, [BASE+RD*8]
  7183.     //|  neg RA
  7184.     //|  add RA, L:RB->top                // RA = (L->top-(L->base+nresults))*8
  7185.     //|  mov PC, [BASE-4]                        // Fetch PC of caller.
  7186.     //|  jmp ->vm_returnc
  7187.     dasm_put(Dst, 14832, Dt1(->base), DISPATCH_GL(cur_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->top));
  7188. #line 5384 "vm_x86.dasc"
  7189.     break;

  7190.   /* ---------------------------------------------------------------------- */

  7191.   default:
  7192.     fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
  7193.     exit(2);
  7194.     break;
  7195.   }
  7196. }

  7197. static int build_backend(BuildCtx *ctx)
  7198. {
  7199.   int op;
  7200.   dasm_growpc(Dst, BC__MAX);
  7201.   build_subroutines(ctx);
  7202.   //|.code_op
  7203.   dasm_put(Dst, 14862);
  7204. #line 5401 "vm_x86.dasc"
  7205.   for (op = 0; op < BC__MAX; op++)
  7206.     build_ins(ctx, (BCOp)op, op);
  7207.   return BC__MAX;
  7208. }

  7209. /* Emit pseudo frame-info for all assembler functions. */
  7210. static void emit_asm_debug(BuildCtx *ctx)
  7211. {
  7212.   int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
  7213. #if LJ_64
  7214. #define SZPTR        "8"
  7215. #define BSZPTR        "3"
  7216. #define REG_SP        "0x7"
  7217. #define REG_RA        "0x10"
  7218. #else
  7219. #define SZPTR        "4"
  7220. #define BSZPTR        "2"
  7221. #define REG_SP        "0x4"
  7222. #define REG_RA        "0x8"
  7223. #endif
  7224.   switch (ctx->mode) {
  7225.   case BUILD_elfasm:
  7226.     fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
  7227.     fprintf(ctx->fp,
  7228.         ".Lframe0:\n"
  7229.         "\t.long .LECIE0-.LSCIE0\n"
  7230.         ".LSCIE0:\n"
  7231.         "\t.long 0xffffffff\n"
  7232.         "\t.byte 0x1\n"
  7233.         "\t.string \"\"\n"
  7234.         "\t.uleb128 0x1\n"
  7235.         "\t.sleb128 -" SZPTR "\n"
  7236.         "\t.byte " REG_RA "\n"
  7237.         "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
  7238.         "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
  7239.         "\t.align " SZPTR "\n"
  7240.         ".LECIE0:\n\n");
  7241.     fprintf(ctx->fp,
  7242.         ".LSFDE0:\n"
  7243.         "\t.long .LEFDE0-.LASFDE0\n"
  7244.         ".LASFDE0:\n"
  7245.         "\t.long .Lframe0\n"
  7246. #if LJ_64
  7247.         "\t.quad .Lbegin\n"
  7248.         "\t.quad %d\n"
  7249.         "\t.byte 0xe\n\t.uleb128 %d\n"                /* def_cfa_offset */
  7250.         "\t.byte 0x86\n\t.uleb128 0x2\n"        /* offset rbp */
  7251.         "\t.byte 0x83\n\t.uleb128 0x3\n"        /* offset rbx */
  7252.         "\t.byte 0x8f\n\t.uleb128 0x4\n"        /* offset r15 */
  7253.         "\t.byte 0x8e\n\t.uleb128 0x5\n"        /* offset r14 */
  7254. #else
  7255.         "\t.long .Lbegin\n"
  7256.         "\t.long %d\n"
  7257.         "\t.byte 0xe\n\t.uleb128 %d\n"                /* def_cfa_offset */
  7258.         "\t.byte 0x85\n\t.uleb128 0x2\n"        /* offset ebp */
  7259.         "\t.byte 0x87\n\t.uleb128 0x3\n"        /* offset edi */
  7260.         "\t.byte 0x86\n\t.uleb128 0x4\n"        /* offset esi */
  7261.         "\t.byte 0x83\n\t.uleb128 0x5\n"        /* offset ebx */
  7262. #endif
  7263.         "\t.align " SZPTR "\n"
  7264.         ".LEFDE0:\n\n", fcofs, CFRAME_SIZE);
  7265. #if LJ_HASFFI
  7266.     fprintf(ctx->fp,
  7267.         ".LSFDE1:\n"
  7268.         "\t.long .LEFDE1-.LASFDE1\n"
  7269.         ".LASFDE1:\n"
  7270.         "\t.long .Lframe0\n"
  7271. #if LJ_64
  7272.         "\t.quad lj_vm_ffi_call\n"
  7273.         "\t.quad %d\n"
  7274.         "\t.byte 0xe\n\t.uleb128 16\n"                /* def_cfa_offset */
  7275.         "\t.byte 0x86\n\t.uleb128 0x2\n"        /* offset rbp */
  7276.         "\t.byte 0xd\n\t.uleb128 0x6\n"                /* def_cfa_register rbp */
  7277.         "\t.byte 0x83\n\t.uleb128 0x3\n"        /* offset rbx */
  7278. #else
  7279.         "\t.long lj_vm_ffi_call\n"
  7280.         "\t.long %d\n"
  7281.         "\t.byte 0xe\n\t.uleb128 8\n"                /* def_cfa_offset */
  7282.         "\t.byte 0x85\n\t.uleb128 0x2\n"        /* offset ebp */
  7283.         "\t.byte 0xd\n\t.uleb128 0x5\n"                /* def_cfa_register ebp */
  7284.         "\t.byte 0x83\n\t.uleb128 0x3\n"        /* offset ebx */
  7285. #endif
  7286.         "\t.align " SZPTR "\n"
  7287.         ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
  7288. #endif
  7289. #if (defined(__sun__) && defined(__svr4__))
  7290. #if LJ_64
  7291.     fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@unwind\n");
  7292. #else
  7293.     fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n");
  7294. #endif
  7295. #else
  7296.     fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
  7297. #endif
  7298.     fprintf(ctx->fp,
  7299.         ".Lframe1:\n"
  7300.         "\t.long .LECIE1-.LSCIE1\n"
  7301.         ".LSCIE1:\n"
  7302.         "\t.long 0\n"
  7303.         "\t.byte 0x1\n"
  7304.         "\t.string \"zPR\"\n"
  7305.         "\t.uleb128 0x1\n"
  7306.         "\t.sleb128 -" SZPTR "\n"
  7307.         "\t.byte " REG_RA "\n"
  7308.         "\t.uleb128 6\n"                        /* augmentation length */
  7309.         "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
  7310.         "\t.long lj_err_unwind_dwarf-.\n"
  7311.         "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
  7312.         "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
  7313.         "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
  7314.         "\t.align " SZPTR "\n"
  7315.         ".LECIE1:\n\n");
  7316.     fprintf(ctx->fp,
  7317.         ".LSFDE2:\n"
  7318.         "\t.long .LEFDE2-.LASFDE2\n"
  7319.         ".LASFDE2:\n"
  7320.         "\t.long .LASFDE2-.Lframe1\n"
  7321.         "\t.long .Lbegin-.\n"
  7322.         "\t.long %d\n"
  7323.         "\t.uleb128 0\n"                        /* augmentation length */
  7324.         "\t.byte 0xe\n\t.uleb128 %d\n"                /* def_cfa_offset */
  7325. #if LJ_64
  7326.         "\t.byte 0x86\n\t.uleb128 0x2\n"        /* offset rbp */
  7327.         "\t.byte 0x83\n\t.uleb128 0x3\n"        /* offset rbx */
  7328.         "\t.byte 0x8f\n\t.uleb128 0x4\n"        /* offset r15 */
  7329.         "\t.byte 0x8e\n\t.uleb128 0x5\n"        /* offset r14 */
  7330. #else
  7331.         "\t.byte 0x85\n\t.uleb128 0x2\n"        /* offset ebp */
  7332.         "\t.byte 0x87\n\t.uleb128 0x3\n"        /* offset edi */
  7333.         "\t.byte 0x86\n\t.uleb128 0x4\n"        /* offset esi */
  7334.         "\t.byte 0x83\n\t.uleb128 0x5\n"        /* offset ebx */
  7335. #endif
  7336.         "\t.align " SZPTR "\n"
  7337.         ".LEFDE2:\n\n", fcofs, CFRAME_SIZE);
  7338. #if LJ_HASFFI
  7339.     fprintf(ctx->fp,
  7340.         ".Lframe2:\n"
  7341.         "\t.long .LECIE2-.LSCIE2\n"
  7342.         ".LSCIE2:\n"
  7343.         "\t.long 0\n"
  7344.         "\t.byte 0x1\n"
  7345.         "\t.string \"zR\"\n"
  7346.         "\t.uleb128 0x1\n"
  7347.         "\t.sleb128 -" SZPTR "\n"
  7348.         "\t.byte " REG_RA "\n"
  7349.         "\t.uleb128 1\n"                        /* augmentation length */
  7350.         "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
  7351.         "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
  7352.         "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
  7353.         "\t.align " SZPTR "\n"
  7354.         ".LECIE2:\n\n");
  7355.     fprintf(ctx->fp,
  7356.         ".LSFDE3:\n"
  7357.         "\t.long .LEFDE3-.LASFDE3\n"
  7358.         ".LASFDE3:\n"
  7359.         "\t.long .LASFDE3-.Lframe2\n"
  7360.         "\t.long lj_vm_ffi_call-.\n"
  7361.         "\t.long %d\n"
  7362.         "\t.uleb128 0\n"                        /* augmentation length */
  7363. #if LJ_64
  7364.         "\t.byte 0xe\n\t.uleb128 16\n"                /* def_cfa_offset */
  7365.         "\t.byte 0x86\n\t.uleb128 0x2\n"        /* offset rbp */
  7366.         "\t.byte 0xd\n\t.uleb128 0x6\n"                /* def_cfa_register rbp */
  7367.         "\t.byte 0x83\n\t.uleb128 0x3\n"        /* offset rbx */
  7368. #else
  7369.         "\t.byte 0xe\n\t.uleb128 8\n"                /* def_cfa_offset */
  7370.         "\t.byte 0x85\n\t.uleb128 0x2\n"        /* offset ebp */
  7371.         "\t.byte 0xd\n\t.uleb128 0x5\n"                /* def_cfa_register ebp */
  7372.         "\t.byte 0x83\n\t.uleb128 0x3\n"        /* offset ebx */
  7373. #endif
  7374.         "\t.align " SZPTR "\n"
  7375.         ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
  7376. #endif
  7377.     break;
  7378.   /* Mental note: never let Apple design an assembler.
  7379.   ** Or a linker. Or a plastic case. But I digress.
  7380.   */
  7381.   case BUILD_machasm: {
  7382. #if LJ_HASFFI
  7383.     int fcsize = 0;
  7384. #endif
  7385.     int i;
  7386.     fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
  7387.     fprintf(ctx->fp,
  7388.         "EH_frame1:\n"
  7389.         "\t.set L$set$x,LECIEX-LSCIEX\n"
  7390.         "\t.long L$set$x\n"
  7391.         "LSCIEX:\n"
  7392.         "\t.long 0\n"
  7393.         "\t.byte 0x1\n"
  7394.         "\t.ascii \"zPR\\0\"\n"
  7395.         "\t.byte 0x1\n"
  7396.         "\t.byte 128-" SZPTR "\n"
  7397.         "\t.byte " REG_RA "\n"
  7398.         "\t.byte 6\n"                                /* augmentation length */
  7399.         "\t.byte 0x9b\n"                        /* indirect|pcrel|sdata4 */
  7400. #if LJ_64
  7401.         "\t.long _lj_err_unwind_dwarf+4@GOTPCREL\n"
  7402.         "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
  7403.         "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
  7404. #else
  7405.         "\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
  7406.         "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
  7407.         "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n"  /* esp=5 on 32 bit MACH-O. */
  7408. #endif
  7409.         "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
  7410.         "\t.align " BSZPTR "\n"
  7411.         "LECIEX:\n\n");
  7412.     for (i = 0; i < ctx->nsym; i++) {
  7413.       const char *name = ctx->sym[i].name;
  7414.       int32_t size = ctx->sym[i+1].ofs - ctx->sym[i].ofs;
  7415.       if (size == 0) continue;
  7416. #if LJ_HASFFI
  7417.       if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; }
  7418. #endif
  7419.       fprintf(ctx->fp,
  7420.           "%s.eh:\n"
  7421.           "LSFDE%d:\n"
  7422.           "\t.set L$set$%d,LEFDE%d-LASFDE%d\n"
  7423.           "\t.long L$set$%d\n"
  7424.           "LASFDE%d:\n"
  7425.           "\t.long LASFDE%d-EH_frame1\n"
  7426.           "\t.long %s-.\n"
  7427.           "\t.long %d\n"
  7428.           "\t.byte 0\n"                                /* augmentation length */
  7429.           "\t.byte 0xe\n\t.byte %d\n"                /* def_cfa_offset */
  7430. #if LJ_64
  7431.           "\t.byte 0x86\n\t.byte 0x2\n"                /* offset rbp */
  7432.           "\t.byte 0x83\n\t.byte 0x3\n"                /* offset rbx */
  7433.           "\t.byte 0x8f\n\t.byte 0x4\n"                /* offset r15 */
  7434.           "\t.byte 0x8e\n\t.byte 0x5\n"                /* offset r14 */
  7435. #else
  7436.           "\t.byte 0x84\n\t.byte 0x2\n"                /* offset ebp (4 for MACH-O)*/
  7437.           "\t.byte 0x87\n\t.byte 0x3\n"                /* offset edi */
  7438.           "\t.byte 0x86\n\t.byte 0x4\n"                /* offset esi */
  7439.           "\t.byte 0x83\n\t.byte 0x5\n"                /* offset ebx */
  7440. #endif
  7441.           "\t.align " BSZPTR "\n"
  7442.           "LEFDE%d:\n\n",
  7443.           name, i, i, i, i, i, i, i, name, size, CFRAME_SIZE, i);
  7444.     }
  7445. #if LJ_HASFFI
  7446.     if (fcsize) {
  7447.       fprintf(ctx->fp,
  7448.           "EH_frame2:\n"
  7449.           "\t.set L$set$y,LECIEY-LSCIEY\n"
  7450.           "\t.long L$set$y\n"
  7451.           "LSCIEY:\n"
  7452.           "\t.long 0\n"
  7453.           "\t.byte 0x1\n"
  7454.           "\t.ascii \"zR\\0\"\n"
  7455.           "\t.byte 0x1\n"
  7456.           "\t.byte 128-" SZPTR "\n"
  7457.           "\t.byte " REG_RA "\n"
  7458.           "\t.byte 1\n"                                /* augmentation length */
  7459. #if LJ_64
  7460.           "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
  7461.           "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
  7462. #else
  7463.           "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
  7464.           "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n"  /* esp=5 on 32 bit MACH. */
  7465. #endif
  7466.           "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
  7467.           "\t.align " BSZPTR "\n"
  7468.           "LECIEY:\n\n");
  7469.       fprintf(ctx->fp,
  7470.           "_lj_vm_ffi_call.eh:\n"
  7471.           "LSFDEY:\n"
  7472.           "\t.set L$set$yy,LEFDEY-LASFDEY\n"
  7473.           "\t.long L$set$yy\n"
  7474.           "LASFDEY:\n"
  7475.           "\t.long LASFDEY-EH_frame2\n"
  7476.           "\t.long _lj_vm_ffi_call-.\n"
  7477.           "\t.long %d\n"
  7478.           "\t.byte 0\n"                                /* augmentation length */
  7479. #if LJ_64
  7480.           "\t.byte 0xe\n\t.byte 16\n"                /* def_cfa_offset */
  7481.           "\t.byte 0x86\n\t.byte 0x2\n"                /* offset rbp */
  7482.           "\t.byte 0xd\n\t.byte 0x6\n"                /* def_cfa_register rbp */
  7483.           "\t.byte 0x83\n\t.byte 0x3\n"                /* offset rbx */
  7484. #else
  7485.           "\t.byte 0xe\n\t.byte 8\n"                /* def_cfa_offset */
  7486.           "\t.byte 0x84\n\t.byte 0x2\n"                /* offset ebp (4 for MACH-O)*/
  7487.           "\t.byte 0xd\n\t.byte 0x4\n"                /* def_cfa_register ebp */
  7488.           "\t.byte 0x83\n\t.byte 0x3\n"                /* offset ebx */
  7489. #endif
  7490.           "\t.align " BSZPTR "\n"
  7491.           "LEFDEY:\n\n", fcsize);
  7492.     }
  7493. #endif
  7494. #if !LJ_64
  7495.     fprintf(ctx->fp,
  7496.       "\t.non_lazy_symbol_pointer\n"
  7497.       "L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
  7498.       ".indirect_symbol _lj_err_unwind_dwarf\n"
  7499.       ".long 0\n\n");
  7500.     fprintf(ctx->fp, "\t.section __IMPORT,__jump_table,symbol_stubs,pure_instructions+self_modifying_code,5\n");
  7501.     {
  7502.       const char *const *xn;
  7503.       for (xn = ctx->extnames; *xn; xn++)
  7504.         if (strncmp(*xn, LABEL_PREFIX, sizeof(LABEL_PREFIX)-1))
  7505.           fprintf(ctx->fp, "L_%s$stub:\n\t.indirect_symbol _%s\n\t.ascii \"\\364\\364\\364\\364\\364\"\n", *xn, *xn);
  7506.     }
  7507. #endif
  7508.     fprintf(ctx->fp, ".subsections_via_symbols\n");
  7509.     }
  7510.     break;
  7511.   default:  /* Difficult for other modes. */
  7512.     break;
  7513.   }
  7514. }