ljx

FORK: LuaJIT with native 5.2 and 5.3 support
git clone https://git.neptards.moe/neptards/ljx.git
Log | Files | Refs | README

vm_ppcspe.dasc (103876B)


      1 |// Low-level VM code for PowerPC/e500 CPUs.
      2 |// Bytecode interpreter, fast functions and helper functions.
      3 |// Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
      4 |
      5 |.arch ppc
      6 |.section code_op, code_sub
      7 |
      8 |.actionlist build_actionlist
      9 |.globals GLOB_
     10 |.globalnames globnames
     11 |.externnames extnames
     12 |
     13 |// Note: The ragged indentation of the instructions is intentional.
     14 |//       The starting columns indicate data dependencies.
     15 |
     16 |//-----------------------------------------------------------------------
     17 |
     18 |// Fixed register assignments for the interpreter.
     19 |// Don't use: r1 = sp, r2 and r13 = reserved and/or small data area ptr
     20 |
     21 |// The following must be C callee-save (but BASE is often refetched).
     22 |.define BASE,		r14	// Base of current Lua stack frame.
     23 |.define KBASE,		r15	// Constants of current Lua function.
     24 |.define PC,		r16	// Next PC.
     25 |.define DISPATCH,	r17	// Opcode dispatch table.
     26 |.define LREG,		r18	// Register holding lua_State (also in SAVE_L).
     27 |.define MULTRES,	r19	// Size of multi-result: (nresults+1)*8.
     28 |
     29 |// Constants for vectorized type-comparisons (hi+low GPR). C callee-save.
     30 |.define TISNUM,	r22
     31 |.define TISSTR,	r23
     32 |.define TISTAB,	r24
     33 |.define TISFUNC,	r25
     34 |.define TISNIL,	r26
     35 |.define TOBIT,		r27
     36 |.define ZERO,		TOBIT	// Zero in lo word.
     37 |
     38 |// The following temporaries are not saved across C calls, except for RA.
     39 |.define RA,		r20	// Callee-save.
     40 |.define RB,		r10
     41 |.define RC,		r11
     42 |.define RD,		r12
     43 |.define INS,		r7	// Overlaps CARG5.
     44 |
     45 |.define TMP0,		r0
     46 |.define TMP1,		r8
     47 |.define TMP2,		r9
     48 |.define TMP3,		r6	// Overlaps CARG4.
     49 |
     50 |// Saved temporaries.
     51 |.define SAVE0,		r21
     52 |
     53 |// Calling conventions.
     54 |.define CARG1,		r3
     55 |.define CARG2,		r4
     56 |.define CARG3,		r5
     57 |.define CARG4,		r6	// Overlaps TMP3.
     58 |.define CARG5,		r7	// Overlaps INS.
     59 |
     60 |.define CRET1,		r3
     61 |.define CRET2,		r4
     62 |
     63 |// Stack layout while in interpreter. Must match with lj_frame.h.
     64 |.define SAVE_LR,	188(sp)
     65 |.define CFRAME_SPACE,	184	// Delta for sp.
     66 |// Back chain for sp:	184(sp)	<-- sp entering interpreter
     67 |.define SAVE_r31,	176(sp)	// 64 bit register saves.
     68 |.define SAVE_r30,	168(sp)
     69 |.define SAVE_r29,	160(sp)
     70 |.define SAVE_r28,	152(sp)
     71 |.define SAVE_r27,	144(sp)
     72 |.define SAVE_r26,	136(sp)
     73 |.define SAVE_r25,	128(sp)
     74 |.define SAVE_r24,	120(sp)
     75 |.define SAVE_r23,	112(sp)
     76 |.define SAVE_r22,	104(sp)
     77 |.define SAVE_r21,	96(sp)
     78 |.define SAVE_r20,	88(sp)
     79 |.define SAVE_r19,	80(sp)
     80 |.define SAVE_r18,	72(sp)
     81 |.define SAVE_r17,	64(sp)
     82 |.define SAVE_r16,	56(sp)
     83 |.define SAVE_r15,	48(sp)
     84 |.define SAVE_r14,	40(sp)
     85 |.define SAVE_CR,	36(sp)
     86 |.define UNUSED1,	32(sp)
     87 |.define SAVE_ERRF,	28(sp)	// 32 bit C frame info.
     88 |.define SAVE_NRES,	24(sp)
     89 |.define SAVE_CFRAME,	20(sp)
     90 |.define SAVE_L,	16(sp)
     91 |.define SAVE_PC,	12(sp)
     92 |.define SAVE_MULTRES,	8(sp)
     93 |// Next frame lr:	4(sp)
     94 |// Back chain for sp:	0(sp)	<-- sp while in interpreter
     95 |
     96 |.macro save_, reg; evstdd reg, SAVE_..reg; .endmacro
     97 |.macro rest_, reg; evldd reg, SAVE_..reg; .endmacro
     98 |
     99 |.macro saveregs
    100 |  stwu sp, -CFRAME_SPACE(sp)
    101 |  save_ r14; save_ r15; save_ r16; save_ r17; save_ r18; save_ r19
    102 |  mflr r0; mfcr r12
    103 |  save_ r20; save_ r21; save_ r22; save_ r23; save_ r24; save_ r25
    104 |  stw  r0, SAVE_LR; stw r12, SAVE_CR
    105 |  save_ r26; save_ r27; save_ r28; save_ r29; save_ r30; save_ r31
    106 |.endmacro
    107 |
    108 |.macro restoreregs
    109 |  lwz r0, SAVE_LR; lwz r12, SAVE_CR
    110 |  rest_ r14; rest_ r15; rest_ r16; rest_ r17; rest_ r18; rest_ r19
    111 |  mtlr r0; mtcrf 0x38, r12
    112 |  rest_ r20; rest_ r21; rest_ r22; rest_ r23; rest_ r24; rest_ r25
    113 |  rest_ r26; rest_ r27; rest_ r28; rest_ r29; rest_ r30; rest_ r31
    114 |  addi sp, sp, CFRAME_SPACE
    115 |.endmacro
    116 |
    117 |// Type definitions. Some of these are only used for documentation.
    118 |.type L,		lua_State,	LREG
    119 |.type GL,		global_State
    120 |.type TVALUE,		TValue
    121 |.type GCOBJ,		GCobj
    122 |.type STR,		GCstr
    123 |.type TAB,		GCtab
    124 |.type LFUNC,		GCfuncL
    125 |.type CFUNC,		GCfuncC
    126 |.type PROTO,		GCproto
    127 |.type UPVAL,		GCupval
    128 |.type NODE,		Node
    129 |.type NARGS8,		int
    130 |.type TRACE,		GCtrace
    131 |
    132 |//-----------------------------------------------------------------------
    133 |
    134 |// These basic macros should really be part of DynASM.
    135 |.macro srwi, rx, ry, n; rlwinm rx, ry, 32-n, n, 31; .endmacro
    136 |.macro slwi, rx, ry, n; rlwinm rx, ry, n, 0, 31-n; .endmacro
    137 |.macro rotlwi, rx, ry, n; rlwinm rx, ry, n, 0, 31; .endmacro
    138 |.macro rotlw, rx, ry, rn; rlwnm rx, ry, rn, 0, 31; .endmacro
    139 |.macro subi, rx, ry, i; addi rx, ry, -i; .endmacro
    140 |
    141 |// Trap for not-yet-implemented parts.
    142 |.macro NYI; tw 4, sp, sp; .endmacro
    143 |
    144 |//-----------------------------------------------------------------------
    145 |
    146 |// Access to frame relative to BASE.
    147 |.define FRAME_PC,	-8
    148 |.define FRAME_FUNC,	-4
    149 |
    150 |// Instruction decode.
    151 |.macro decode_OP4, dst, ins; rlwinm dst, ins, 2, 22, 29; .endmacro
    152 |.macro decode_RA8, dst, ins; rlwinm dst, ins, 27, 21, 28; .endmacro
    153 |.macro decode_RB8, dst, ins; rlwinm dst, ins, 11, 21, 28; .endmacro
    154 |.macro decode_RC8, dst, ins; rlwinm dst, ins, 19, 21, 28; .endmacro
    155 |.macro decode_RD8, dst, ins; rlwinm dst, ins, 19, 13, 28; .endmacro
    156 |
    157 |.macro decode_OP1, dst, ins; rlwinm dst, ins, 0, 24, 31; .endmacro
    158 |.macro decode_RD4, dst, ins; rlwinm dst, ins, 18, 14, 29; .endmacro
    159 |
    160 |// Instruction fetch.
    161 |.macro ins_NEXT1
    162 |  lwz INS, 0(PC)
    163 |   addi PC, PC, 4
    164 |.endmacro
    165 |// Instruction decode+dispatch.
    166 |.macro ins_NEXT2
    167 |  decode_OP4 TMP1, INS
    168 |   decode_RB8 RB, INS
    169 |   decode_RD8 RD, INS
    170 |  lwzx TMP0, DISPATCH, TMP1
    171 |   decode_RA8 RA, INS
    172 |   decode_RC8 RC, INS
    173 |  mtctr TMP0
    174 |  bctr
    175 |.endmacro
    176 |.macro ins_NEXT
    177 |  ins_NEXT1
    178 |  ins_NEXT2
    179 |.endmacro
    180 |
    181 |// Instruction footer.
    182 |.if 1
    183 |  // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
    184 |  .define ins_next, ins_NEXT
    185 |  .define ins_next_, ins_NEXT
    186 |  .define ins_next1, ins_NEXT1
    187 |  .define ins_next2, ins_NEXT2
    188 |.else
    189 |  // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
    190 |  // Affects only certain kinds of benchmarks (and only with -j off).
    191 |  .macro ins_next
    192 |    b ->ins_next
    193 |  .endmacro
    194 |  .macro ins_next1
    195 |  .endmacro
    196 |  .macro ins_next2
    197 |    b ->ins_next
    198 |  .endmacro
    199 |  .macro ins_next_
    200 |  ->ins_next:
    201 |    ins_NEXT
    202 |  .endmacro
    203 |.endif
    204 |
    205 |// Call decode and dispatch.
    206 |.macro ins_callt
    207 |  // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
    208 |  lwz PC, LFUNC:RB->pc
    209 |  lwz INS, 0(PC)
    210 |   addi PC, PC, 4
    211 |  decode_OP4 TMP1, INS
    212 |   decode_RA8 RA, INS
    213 |  lwzx TMP0, DISPATCH, TMP1
    214 |   add RA, RA, BASE
    215 |  mtctr TMP0
    216 |  bctr
    217 |.endmacro
    218 |
    219 |.macro ins_call
    220 |  // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, PC = caller PC
    221 |  stw PC, FRAME_PC(BASE)
    222 |  ins_callt
    223 |.endmacro
    224 |
    225 |//-----------------------------------------------------------------------
    226 |
    227 |// Macros to test operand types.
    228 |.macro checknum, reg; evcmpltu reg, TISNUM; .endmacro
    229 |.macro checkstr, reg; evcmpeq reg, TISSTR; .endmacro
    230 |.macro checktab, reg; evcmpeq reg, TISTAB; .endmacro
    231 |.macro checkfunc, reg; evcmpeq reg, TISFUNC; .endmacro
    232 |.macro checknil, reg; evcmpeq reg, TISNIL; .endmacro
    233 |.macro checkok, label; blt label; .endmacro
    234 |.macro checkfail, label; bge label; .endmacro
    235 |.macro checkanyfail, label; bns label; .endmacro
    236 |.macro checkallok, label; bso label; .endmacro
    237 |
    238 |.macro branch_RD
    239 |  srwi TMP0, RD, 1
    240 |  add PC, PC, TMP0
    241 |  addis PC, PC, -(BCBIAS_J*4 >> 16)
    242 |.endmacro
    243 |
    244 |// Assumes DISPATCH is relative to GL.
    245 #define DISPATCH_GL(field)	(GG_DISP2G + (int)offsetof(global_State, field))
    246 #define DISPATCH_J(field)	(GG_DISP2J + (int)offsetof(jit_State, field))
    247 |
    248 #define PC2PROTO(field)  ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
    249 |
    250 |.macro hotloop
    251 |  NYI
    252 |.endmacro
    253 |
    254 |.macro hotcall
    255 |  NYI
    256 |.endmacro
    257 |
    258 |// Set current VM state. Uses TMP0.
    259 |.macro li_vmstate, st; li TMP0, ~LJ_VMST_..st; .endmacro
    260 |.macro st_vmstate; stw TMP0, DISPATCH_GL(vmstate)(DISPATCH); .endmacro
    261 |
    262 |// Move table write barrier back. Overwrites mark and tmp.
    263 |.macro barrierback, tab, mark, tmp
    264 |  lwz tmp, DISPATCH_GL(gc.grayagain)(DISPATCH)
    265 |  // Assumes LJ_GC_BLACK is 0x04.
    266 |   rlwinm mark, mark, 0, 30, 28		// black2gray(tab)
    267 |  stw tab, DISPATCH_GL(gc.grayagain)(DISPATCH)
    268 |   stb mark, tab->marked
    269 |  stw tmp, tab->gclist
    270 |.endmacro
    271 |
    272 |//-----------------------------------------------------------------------
    273 
    274 /* Generate subroutines used by opcodes and other parts of the VM. */
    275 /* The .code_sub section should be last to help static branch prediction. */
    276 static void build_subroutines(BuildCtx *ctx)
    277 {
    278   |.code_sub
    279   |
    280   |//-----------------------------------------------------------------------
    281   |//-- Return handling ----------------------------------------------------
    282   |//-----------------------------------------------------------------------
    283   |
    284   |->vm_returnp:
    285   |  // See vm_return. Also: TMP2 = previous base.
    286   |  andi. TMP0, PC, FRAME_P
    287   |   evsplati TMP1, LJ_TTRUE
    288   |  beq ->cont_dispatch
    289   |
    290   |  // Return from pcall or xpcall fast func.
    291   |  lwz PC, FRAME_PC(TMP2)		// Fetch PC of previous frame.
    292   |  mr BASE, TMP2			// Restore caller base.
    293   |  // Prepending may overwrite the pcall frame, so do it at the end.
    294   |   stwu TMP1, FRAME_PC(RA)		// Prepend true to results.
    295   |
    296   |->vm_returnc:
    297   |  addi RD, RD, 8			// RD = (nresults+1)*8.
    298   |   andi. TMP0, PC, FRAME_TYPE
    299   |  cmpwi cr1, RD, 0
    300   |  li CRET1, LUA_YIELD
    301   |  beq cr1, ->vm_unwind_c_eh
    302   |  mr MULTRES, RD
    303   |   beq ->BC_RET_Z			// Handle regular return to Lua.
    304   |
    305   |->vm_return:
    306   |  // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return
    307   |  // TMP0 = PC & FRAME_TYPE
    308   |  cmpwi TMP0, FRAME_C
    309   |   rlwinm TMP2, PC, 0, 0, 28
    310   |    li_vmstate C
    311   |   sub TMP2, BASE, TMP2		// TMP2 = previous base.
    312   |  bne ->vm_returnp
    313   |
    314   |  addic. TMP1, RD, -8
    315   |   stw TMP2, L->base
    316   |   lwz TMP2, SAVE_NRES
    317   |    subi BASE, BASE, 8
    318   |    st_vmstate
    319   |   slwi TMP2, TMP2, 3
    320   |  beq >2
    321   |1:
    322   |  addic. TMP1, TMP1, -8
    323   |   evldd TMP0, 0(RA)
    324   |    addi RA, RA, 8
    325   |   evstdd TMP0, 0(BASE)
    326   |    addi BASE, BASE, 8
    327   |  bne <1
    328   |
    329   |2:
    330   |  cmpw TMP2, RD			// More/less results wanted?
    331   |  bne >6
    332   |3:
    333   |  stw BASE, L->top			// Store new top.
    334   |
    335   |->vm_leave_cp:
    336   |  lwz TMP0, SAVE_CFRAME		// Restore previous C frame.
    337   |   li CRET1, 0			// Ok return status for vm_pcall.
    338   |  stw TMP0, L->cframe
    339   |
    340   |->vm_leave_unw:
    341   |  restoreregs
    342   |  blr
    343   |
    344   |6:
    345   |  ble >7				// Less results wanted?
    346   |  // More results wanted. Check stack size and fill up results with nil.
    347   |  lwz TMP1, L->maxstack
    348   |  cmplw BASE, TMP1
    349   |  bge >8
    350   |  evstdd TISNIL, 0(BASE)
    351   |  addi RD, RD, 8
    352   |  addi BASE, BASE, 8
    353   |  b <2
    354   |
    355   |7:  // Less results wanted.
    356   |   sub TMP0, RD, TMP2
    357   |  cmpwi TMP2, 0			// LUA_MULTRET+1 case?
    358   |   sub TMP0, BASE, TMP0		// Subtract the difference.
    359   |  iseleq BASE, BASE, TMP0		// Either keep top or shrink it.
    360   |  b <3
    361   |
    362   |8:  // Corner case: need to grow stack for filling up results.
    363   |  // This can happen if:
    364   |  // - A C function grows the stack (a lot).
    365   |  // - The GC shrinks the stack in between.
    366   |  // - A return back from a lua_call() with (high) nresults adjustment.
    367   |  stw BASE, L->top			// Save current top held in BASE (yes).
    368   |   mr SAVE0, RD
    369   |  mr CARG2, TMP2
    370   |  mr CARG1, L
    371   |  bl extern lj_state_growstack	// (lua_State *L, int n)
    372   |    lwz TMP2, SAVE_NRES
    373   |   mr RD, SAVE0
    374   |    slwi TMP2, TMP2, 3
    375   |  lwz BASE, L->top			// Need the (realloced) L->top in BASE.
    376   |  b <2
    377   |
    378   |->vm_unwind_c:			// Unwind C stack, return from vm_pcall.
    379   |  // (void *cframe, int errcode)
    380   |  mr sp, CARG1
    381   |  mr CRET1, CARG2
    382   |->vm_unwind_c_eh:			// Landing pad for external unwinder.
    383   |  lwz L, SAVE_L
    384   |   li TMP0, ~LJ_VMST_C
    385   |  lwz GL:TMP1, L->glref
    386   |   stw TMP0, GL:TMP1->vmstate
    387   |  b ->vm_leave_unw
    388   |
    389   |->vm_unwind_ff:			// Unwind C stack, return from ff pcall.
    390   |  // (void *cframe)
    391   |  rlwinm sp, CARG1, 0, 0, 29
    392   |->vm_unwind_ff_eh:			// Landing pad for external unwinder.
    393   |  lwz L, SAVE_L
    394   |     evsplati TISNUM, LJ_TISNUM+1	// Setup type comparison constants.
    395   |     evsplati TISFUNC, LJ_TFUNC
    396   |     lus TOBIT, 0x4338
    397   |     evsplati TISTAB, LJ_TTAB
    398   |     li TMP0, 0
    399   |  lwz BASE, L->base
    400   |     evmergelo TOBIT, TOBIT, TMP0
    401   |   lwz DISPATCH, L->glref		// Setup pointer to dispatch table.
    402   |     evsplati TISSTR, LJ_TSTR
    403   |  li TMP1, LJ_TFALSE
    404   |     evsplati TISNIL, LJ_TNIL
    405   |    li_vmstate INTERP
    406   |  lwz PC, FRAME_PC(BASE)		// Fetch PC of previous frame.
    407   |  la RA, -8(BASE)			// Results start at BASE-8.
    408   |   addi DISPATCH, DISPATCH, GG_G2DISP
    409   |  stw TMP1, 0(RA)			// Prepend false to error message.
    410   |  li RD, 16				// 2 results: false + error message.
    411   |    st_vmstate
    412   |  b ->vm_returnc
    413   |
    414   |//-----------------------------------------------------------------------
    415   |//-- Grow stack for calls -----------------------------------------------
    416   |//-----------------------------------------------------------------------
    417   |
    418   |->vm_growstack_c:			// Grow stack for C function.
    419   |  li CARG2, LUA_MINSTACK
    420   |  b >2
    421   |
    422   |->vm_growstack_l:			// Grow stack for Lua function.
    423   |  // BASE = new base, RA = BASE+framesize*8, RC = nargs*8, PC = first PC
    424   |  add RC, BASE, RC
    425   |   sub RA, RA, BASE
    426   |  stw BASE, L->base
    427   |   addi PC, PC, 4			// Must point after first instruction.
    428   |  stw RC, L->top
    429   |   srwi CARG2, RA, 3
    430   |2:
    431   |  // L->base = new base, L->top = top
    432   |   stw PC, SAVE_PC
    433   |  mr CARG1, L
    434   |  bl extern lj_state_growstack	// (lua_State *L, int n)
    435   |  lwz BASE, L->base
    436   |  lwz RC, L->top
    437   |  lwz LFUNC:RB, FRAME_FUNC(BASE)
    438   |  sub RC, RC, BASE
    439   |  // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
    440   |  ins_callt				// Just retry the call.
    441   |
    442   |//-----------------------------------------------------------------------
    443   |//-- Entry points into the assembler VM ---------------------------------
    444   |//-----------------------------------------------------------------------
    445   |
    446   |->vm_resume:				// Setup C frame and resume thread.
    447   |  // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
    448   |  saveregs
    449   |  mr L, CARG1
    450   |    lwz DISPATCH, L->glref		// Setup pointer to dispatch table.
    451   |  mr BASE, CARG2
    452   |    lbz TMP1, L->status
    453   |   stw L, SAVE_L
    454   |  li PC, FRAME_CP
    455   |  addi TMP0, sp, CFRAME_RESUME
    456   |    addi DISPATCH, DISPATCH, GG_G2DISP
    457   |   stw CARG3, SAVE_NRES
    458   |    cmplwi TMP1, 0
    459   |   stw CARG3, SAVE_ERRF
    460   |  stw TMP0, L->cframe
    461   |   stw CARG3, SAVE_CFRAME
    462   |   stw CARG1, SAVE_PC		// Any value outside of bytecode is ok.
    463   |    beq >3
    464   |
    465   |  // Resume after yield (like a return).
    466   |  mr RA, BASE
    467   |   lwz BASE, L->base
    468   |    evsplati TISNUM, LJ_TISNUM+1	// Setup type comparison constants.
    469   |   lwz TMP1, L->top
    470   |    evsplati TISFUNC, LJ_TFUNC
    471   |    lus TOBIT, 0x4338
    472   |    evsplati TISTAB, LJ_TTAB
    473   |  lwz PC, FRAME_PC(BASE)
    474   |    li TMP2, 0
    475   |    evsplati TISSTR, LJ_TSTR
    476   |   sub RD, TMP1, BASE
    477   |    evmergelo TOBIT, TOBIT, TMP2
    478   |    stb CARG3, L->status
    479   |  andi. TMP0, PC, FRAME_TYPE
    480   |    li_vmstate INTERP
    481   |   addi RD, RD, 8
    482   |    evsplati TISNIL, LJ_TNIL
    483   |   mr MULTRES, RD
    484   |    st_vmstate
    485   |  beq ->BC_RET_Z
    486   |  b ->vm_return
    487   |
    488   |->vm_pcall:				// Setup protected C frame and enter VM.
    489   |  // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
    490   |  saveregs
    491   |  li PC, FRAME_CP
    492   |  stw CARG4, SAVE_ERRF
    493   |  b >1
    494   |
    495   |->vm_call:				// Setup C frame and enter VM.
    496   |  // (lua_State *L, TValue *base, int nres1)
    497   |  saveregs
    498   |  li PC, FRAME_C
    499   |
    500   |1:  // Entry point for vm_pcall above (PC = ftype).
    501   |  lwz TMP1, L:CARG1->cframe
    502   |   stw CARG3, SAVE_NRES
    503   |    mr L, CARG1
    504   |   stw CARG1, SAVE_L
    505   |    mr BASE, CARG2
    506   |  stw sp, L->cframe			// Add our C frame to cframe chain.
    507   |    lwz DISPATCH, L->glref		// Setup pointer to dispatch table.
    508   |   stw CARG1, SAVE_PC		// Any value outside of bytecode is ok.
    509   |  stw TMP1, SAVE_CFRAME
    510   |    addi DISPATCH, DISPATCH, GG_G2DISP
    511   |
    512   |3:  // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
    513   |  lwz TMP2, L->base			// TMP2 = old base (used in vmeta_call).
    514   |    evsplati TISNUM, LJ_TISNUM+1	// Setup type comparison constants.
    515   |   lwz TMP1, L->top
    516   |    evsplati TISFUNC, LJ_TFUNC
    517   |  add PC, PC, BASE
    518   |    evsplati TISTAB, LJ_TTAB
    519   |    lus TOBIT, 0x4338
    520   |    li TMP0, 0
    521   |  sub PC, PC, TMP2			// PC = frame delta + frame type
    522   |    evsplati TISSTR, LJ_TSTR
    523   |   sub NARGS8:RC, TMP1, BASE
    524   |    evmergelo TOBIT, TOBIT, TMP0
    525   |    li_vmstate INTERP
    526   |    evsplati TISNIL, LJ_TNIL
    527   |    st_vmstate
    528   |
    529   |->vm_call_dispatch:
    530   |  // TMP2 = old base, BASE = new base, RC = nargs*8, PC = caller PC
    531   |  li TMP0, -8
    532   |  evlddx LFUNC:RB, BASE, TMP0
    533   |  checkfunc LFUNC:RB
    534   |  checkfail ->vmeta_call
    535   |
    536   |->vm_call_dispatch_f:
    537   |  ins_call
    538   |  // BASE = new base, RB = func, RC = nargs*8, PC = caller PC
    539   |
    540   |->vm_cpcall:				// Setup protected C frame, call C.
    541   |  // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
    542   |  saveregs
    543   |  mr L, CARG1
    544   |   lwz TMP0, L:CARG1->stack
    545   |  stw CARG1, SAVE_L
    546   |   lwz TMP1, L->top
    547   |  stw CARG1, SAVE_PC			// Any value outside of bytecode is ok.
    548   |   sub TMP0, TMP0, TMP1		// Compute -savestack(L, L->top).
    549   |    lwz TMP1, L->cframe
    550   |    stw sp, L->cframe		// Add our C frame to cframe chain.
    551   |  li TMP2, 0
    552   |   stw TMP0, SAVE_NRES		// Neg. delta means cframe w/o frame.
    553   |  stw TMP2, SAVE_ERRF		// No error function.
    554   |    stw TMP1, SAVE_CFRAME
    555   |  mtctr CARG4
    556   |  bctrl			// (lua_State *L, lua_CFunction func, void *ud)
    557   |  mr. BASE, CRET1
    558   |   lwz DISPATCH, L->glref		// Setup pointer to dispatch table.
    559   |    li PC, FRAME_CP
    560   |   addi DISPATCH, DISPATCH, GG_G2DISP
    561   |  bne <3				// Else continue with the call.
    562   |  b ->vm_leave_cp			// No base? Just remove C frame.
    563   |
    564   |//-----------------------------------------------------------------------
    565   |//-- Metamethod handling ------------------------------------------------
    566   |//-----------------------------------------------------------------------
    567   |
    568   |// The lj_meta_* functions (except for lj_meta_cat) don't reallocate the
    569   |// stack, so BASE doesn't need to be reloaded across these calls.
    570   |
    571   |//-- Continuation dispatch ----------------------------------------------
    572   |
    573   |->cont_dispatch:
    574   |  // BASE = meta base, RA = resultptr, RD = (nresults+1)*8
    575   |  lwz TMP0, -12(BASE)		// Continuation.
    576   |   mr RB, BASE
    577   |   mr BASE, TMP2			// Restore caller BASE.
    578   |    lwz LFUNC:TMP1, FRAME_FUNC(TMP2)
    579   |  cmplwi TMP0, 0
    580   |     lwz PC, -16(RB)			// Restore PC from [cont|PC].
    581   |  beq >1
    582   |   subi TMP2, RD, 8
    583   |    lwz TMP1, LFUNC:TMP1->pc
    584   |   evstddx TISNIL, RA, TMP2		// Ensure one valid arg.
    585   |    lwz KBASE, PC2PROTO(k)(TMP1)
    586   |  // BASE = base, RA = resultptr, RB = meta base
    587   |  mtctr TMP0
    588   |  bctr				// Jump to continuation.
    589   |
    590   |1:  // Tail call from C function.
    591   |  subi TMP1, RB, 16
    592   |  sub RC, TMP1, BASE
    593   |  b ->vm_call_tail
    594   |
    595   |->cont_cat:				// RA = resultptr, RB = meta base
    596   |  lwz INS, -4(PC)
    597   |   subi CARG2, RB, 16
    598   |  decode_RB8 SAVE0, INS
    599   |   evldd TMP0, 0(RA)
    600   |  add TMP1, BASE, SAVE0
    601   |   stw BASE, L->base
    602   |  cmplw TMP1, CARG2
    603   |   sub CARG3, CARG2, TMP1
    604   |  decode_RA8 RA, INS
    605   |   evstdd TMP0, 0(CARG2)
    606   |  bne ->BC_CAT_Z
    607   |   evstddx TMP0, BASE, RA
    608   |  b ->cont_nop
    609   |
    610   |//-- Table indexing metamethods -----------------------------------------
    611   |
    612   |->vmeta_tgets1:
    613   |  evmergelo STR:RC, TISSTR, STR:RC
    614   |  la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
    615   |   decode_RB8 RB, INS
    616   |  evstdd STR:RC, 0(CARG3)
    617   |   add CARG2, BASE, RB
    618   |  b >1
    619   |
    620   |->vmeta_tgets:
    621   |  evmergelo TAB:RB, TISTAB, TAB:RB
    622   |  la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
    623   |   evmergelo STR:RC, TISSTR, STR:RC
    624   |  evstdd TAB:RB, 0(CARG2)
    625   |   la CARG3, DISPATCH_GL(tmptv2)(DISPATCH)
    626   |   evstdd STR:RC, 0(CARG3)
    627   |  b >1
    628   |
    629   |->vmeta_tgetb:			// TMP0 = index
    630   |  efdcfsi TMP0, TMP0
    631   |   decode_RB8 RB, INS
    632   |  la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
    633   |   add CARG2, BASE, RB
    634   |  evstdd TMP0, 0(CARG3)
    635   |  b >1
    636   |
    637   |->vmeta_tgetv:
    638   |  decode_RB8 RB, INS
    639   |   decode_RC8 RC, INS
    640   |  add CARG2, BASE, RB
    641   |   add CARG3, BASE, RC
    642   |1:
    643   |  stw BASE, L->base
    644   |  mr CARG1, L
    645   |  stw PC, SAVE_PC
    646   |  bl extern lj_meta_tget		// (lua_State *L, TValue *o, TValue *k)
    647   |  // Returns TValue * (finished) or NULL (metamethod).
    648   |  cmplwi CRET1, 0
    649   |  beq >3
    650   |  evldd TMP0, 0(CRET1)
    651   |  evstddx TMP0, BASE, RA
    652   |  ins_next
    653   |
    654   |3:  // Call __index metamethod.
    655   |  // BASE = base, L->top = new base, stack = cont/func/t/k
    656   |  subfic TMP1, BASE, FRAME_CONT
    657   |  lwz BASE, L->top
    658   |  stw PC, -16(BASE)			// [cont|PC]
    659   |   add PC, TMP1, BASE
    660   |  lwz LFUNC:RB, FRAME_FUNC(BASE)	// Guaranteed to be a function here.
    661   |   li NARGS8:RC, 16			// 2 args for func(t, k).
    662   |  b ->vm_call_dispatch_f
    663   |
    664   |//-----------------------------------------------------------------------
    665   |
    666   |->vmeta_tsets1:
    667   |  evmergelo STR:RC, TISSTR, STR:RC
    668   |  la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
    669   |   decode_RB8 RB, INS
    670   |  evstdd STR:RC, 0(CARG3)
    671   |   add CARG2, BASE, RB
    672   |  b >1
    673   |
    674   |->vmeta_tsets:
    675   |  evmergelo TAB:RB, TISTAB, TAB:RB
    676   |  la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
    677   |   evmergelo STR:RC, TISSTR, STR:RC
    678   |  evstdd TAB:RB, 0(CARG2)
    679   |   la CARG3, DISPATCH_GL(tmptv2)(DISPATCH)
    680   |   evstdd STR:RC, 0(CARG3)
    681   |  b >1
    682   |
    683   |->vmeta_tsetb:			// TMP0 = index
    684   |  efdcfsi TMP0, TMP0
    685   |   decode_RB8 RB, INS
    686   |  la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
    687   |   add CARG2, BASE, RB
    688   |  evstdd TMP0, 0(CARG3)
    689   |  b >1
    690   |
    691   |->vmeta_tsetv:
    692   |  decode_RB8 RB, INS
    693   |   decode_RC8 RC, INS
    694   |  add CARG2, BASE, RB
    695   |   add CARG3, BASE, RC
    696   |1:
    697   |  stw BASE, L->base
    698   |  mr CARG1, L
    699   |  stw PC, SAVE_PC
    700   |  bl extern lj_meta_tset		// (lua_State *L, TValue *o, TValue *k)
    701   |  // Returns TValue * (finished) or NULL (metamethod).
    702   |  cmplwi CRET1, 0
    703   |   evlddx TMP0, BASE, RA
    704   |  beq >3
    705   |  // NOBARRIER: lj_meta_tset ensures the table is not black.
    706   |   evstdd TMP0, 0(CRET1)
    707   |  ins_next
    708   |
    709   |3:  // Call __newindex metamethod.
    710   |  // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
    711   |  subfic TMP1, BASE, FRAME_CONT
    712   |  lwz BASE, L->top
    713   |  stw PC, -16(BASE)			// [cont|PC]
    714   |   add PC, TMP1, BASE
    715   |  lwz LFUNC:RB, FRAME_FUNC(BASE)	// Guaranteed to be a function here.
    716   |   li NARGS8:RC, 24			// 3 args for func(t, k, v)
    717   |  evstdd TMP0, 16(BASE)		// Copy value to third argument.
    718   |  b ->vm_call_dispatch_f
    719   |
    720   |//-- Comparison metamethods ---------------------------------------------
    721   |
    722   |->vmeta_comp:
    723   |  mr CARG1, L
    724   |   subi PC, PC, 4
    725   |  add CARG2, BASE, RA
    726   |   stw PC, SAVE_PC
    727   |  add CARG3, BASE, RD
    728   |   stw BASE, L->base
    729   |  decode_OP1 CARG4, INS
    730   |  bl extern lj_meta_comp  // (lua_State *L, TValue *o1, *o2, int op)
    731   |  // Returns 0/1 or TValue * (metamethod).
    732   |3:
    733   |  cmplwi CRET1, 1
    734   |  bgt ->vmeta_binop
    735   |4:
    736   |  lwz INS, 0(PC)
    737   |   addi PC, PC, 4
    738   |  decode_RD4 TMP2, INS
    739   |  addis TMP3, PC, -(BCBIAS_J*4 >> 16)
    740   |  add TMP2, TMP2, TMP3
    741   |  isellt PC, PC, TMP2
    742   |->cont_nop:
    743   |  ins_next
    744   |
    745   |->cont_ra:				// RA = resultptr
    746   |  lwz INS, -4(PC)
    747   |   evldd TMP0, 0(RA)
    748   |  decode_RA8 TMP1, INS
    749   |   evstddx TMP0, BASE, TMP1
    750   |  b ->cont_nop
    751   |
    752   |->cont_condt:			// RA = resultptr
    753   |  lwz TMP0, 0(RA)
    754   |   li TMP1, LJ_TTRUE
    755   |  cmplw TMP1, TMP0			// Branch if result is true.
    756   |  b <4
    757   |
    758   |->cont_condf:			// RA = resultptr
    759   |  lwz TMP0, 0(RA)
    760   |   li TMP1, LJ_TFALSE
    761   |  cmplw TMP0, TMP1			// Branch if result is false.
    762   |  b <4
    763   |
    764   |->vmeta_equal:
    765   |  // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV.
    766   |  subi PC, PC, 4
    767   |   stw BASE, L->base
    768   |  mr CARG1, L
    769   |   stw PC, SAVE_PC
    770   |  bl extern lj_meta_equal  // (lua_State *L, GCobj *o1, *o2, int ne)
    771   |  // Returns 0/1 or TValue * (metamethod).
    772   |  b <3
    773   |
    774   |//-- Arithmetic metamethods ---------------------------------------------
    775   |
    776   |->vmeta_arith_vn:
    777   |  add CARG3, BASE, RB
    778   |  add CARG4, KBASE, RC
    779   |  b >1
    780   |
    781   |->vmeta_arith_nv:
    782   |  add CARG3, KBASE, RC
    783   |  add CARG4, BASE, RB
    784   |  b >1
    785   |
    786   |->vmeta_unm:
    787   |  add CARG3, BASE, RD
    788   |  mr CARG4, CARG3
    789   |  b >1
    790   |
    791   |->vmeta_arith_vv:
    792   |  add CARG3, BASE, RB
    793   |  add CARG4, BASE, RC
    794   |1:
    795   |  add CARG2, BASE, RA
    796   |   stw BASE, L->base
    797   |  mr CARG1, L
    798   |   stw PC, SAVE_PC
    799   |  decode_OP1 CARG5, INS		// Caveat: CARG5 overlaps INS.
    800   |  bl extern lj_meta_arith  // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
    801   |  // Returns NULL (finished) or TValue * (metamethod).
    802   |  cmplwi CRET1, 0
    803   |  beq ->cont_nop
    804   |
    805   |  // Call metamethod for binary op.
    806   |->vmeta_binop:
    807   |  // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2
    808   |  sub TMP1, CRET1, BASE
    809   |   stw PC, -16(CRET1)		// [cont|PC]
    810   |   mr TMP2, BASE
    811   |  addi PC, TMP1, FRAME_CONT
    812   |   mr BASE, CRET1
    813   |  li NARGS8:RC, 16			// 2 args for func(o1, o2).
    814   |  b ->vm_call_dispatch
    815   |
    816   |->vmeta_len:
    817   |  mr SAVE0, CARG1
    818   |  add CARG2, BASE, RD
    819   |   stw BASE, L->base
    820   |  mr CARG1, L
    821   |   stw PC, SAVE_PC
    822   |  bl extern lj_meta_len		// (lua_State *L, TValue *o)
    823   |  // Returns NULL (retry) or TValue * (metamethod base).
    824   |  cmplwi CRET1, 0
    825   |  bne ->vmeta_binop			// Binop call for compatibility.
    826   |  mr CARG1, SAVE0
    827   |  b ->BC_LEN_Z
    828   |
    829   |//-- Call metamethod ----------------------------------------------------
    830   |
    831   |->vmeta_call:			// Resolve and call __call metamethod.
    832   |  // TMP2 = old base, BASE = new base, RC = nargs*8
    833   |  mr CARG1, L
    834   |   stw TMP2, L->base			// This is the callers base!
    835   |  subi CARG2, BASE, 8
    836   |   stw PC, SAVE_PC
    837   |  add CARG3, BASE, RC
    838   |   mr SAVE0, NARGS8:RC
    839   |  bl extern lj_meta_call	// (lua_State *L, TValue *func, TValue *top)
    840   |  lwz LFUNC:RB, FRAME_FUNC(BASE)	// Guaranteed to be a function here.
    841   |   addi NARGS8:RC, SAVE0, 8		// Got one more argument now.
    842   |  ins_call
    843   |
    844   |->vmeta_callt:			// Resolve __call for BC_CALLT.
    845   |  // BASE = old base, RA = new base, RC = nargs*8
    846   |  mr CARG1, L
    847   |   stw BASE, L->base
    848   |  subi CARG2, RA, 8
    849   |   stw PC, SAVE_PC
    850   |  add CARG3, RA, RC
    851   |   mr SAVE0, NARGS8:RC
    852   |  bl extern lj_meta_call	// (lua_State *L, TValue *func, TValue *top)
    853   |  lwz TMP1, FRAME_PC(BASE)
    854   |   addi NARGS8:RC, SAVE0, 8		// Got one more argument now.
    855   |   lwz LFUNC:RB, FRAME_FUNC(RA)	// Guaranteed to be a function here.
    856   |  b ->BC_CALLT_Z
    857   |
    858   |//-- Argument coercion for 'for' statement ------------------------------
    859   |
    860   |->vmeta_for:
    861   |  mr CARG1, L
    862   |   stw BASE, L->base
    863   |  mr CARG2, RA
    864   |   stw PC, SAVE_PC
    865   |  mr SAVE0, INS
    866   |  bl extern lj_meta_for	// (lua_State *L, TValue *base)
    867   |.if JIT
    868   |   decode_OP1 TMP0, SAVE0
    869   |.endif
    870   |  decode_RA8 RA, SAVE0
    871   |.if JIT
    872   |   cmpwi TMP0, BC_JFORI
    873   |.endif
    874   |  decode_RD8 RD, SAVE0
    875   |.if JIT
    876   |   beq =>BC_JFORI
    877   |.endif
    878   |  b =>BC_FORI
    879   |
    880   |//-----------------------------------------------------------------------
    881   |//-- Fast functions -----------------------------------------------------
    882   |//-----------------------------------------------------------------------
    883   |
    884   |.macro .ffunc, name
    885   |->ff_ .. name:
    886   |.endmacro
    887   |
    888   |.macro .ffunc_1, name
    889   |->ff_ .. name:
    890   |  cmplwi NARGS8:RC, 8
    891   |   evldd CARG1, 0(BASE)
    892   |  blt ->fff_fallback
    893   |.endmacro
    894   |
    895   |.macro .ffunc_2, name
    896   |->ff_ .. name:
    897   |  cmplwi NARGS8:RC, 16
    898   |   evldd CARG1, 0(BASE)
    899   |   evldd CARG2, 8(BASE)
    900   |  blt ->fff_fallback
    901   |.endmacro
    902   |
    903   |.macro .ffunc_n, name
    904   |  .ffunc_1 name
    905   |  checknum CARG1
    906   |  checkfail ->fff_fallback
    907   |.endmacro
    908   |
    909   |.macro .ffunc_nn, name
    910   |  .ffunc_2 name
    911   |  evmergehi TMP0, CARG1, CARG2
    912   |  checknum TMP0
    913   |  checkanyfail ->fff_fallback
    914   |.endmacro
    915   |
    916   |// Inlined GC threshold check. Caveat: uses TMP0 and TMP1.
    917   |.macro ffgccheck
    918   |  lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
    919   |  lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
    920   |  cmplw TMP0, TMP1
    921   |  bgel ->fff_gcstep
    922   |.endmacro
    923   |
    924   |//-- Base library: checks -----------------------------------------------
    925   |
    926   |.ffunc assert
    927   |  cmplwi NARGS8:RC, 8
    928   |   evldd TMP0, 0(BASE)
    929   |  blt ->fff_fallback
    930   |  evaddw TMP1, TISNIL, TISNIL	// Synthesize LJ_TFALSE.
    931   |  la RA, -8(BASE)
    932   |   evcmpltu cr1, TMP0, TMP1
    933   |    lwz PC, FRAME_PC(BASE)
    934   |  bge cr1, ->fff_fallback
    935   |   evstdd TMP0, 0(RA)
    936   |  addi RD, NARGS8:RC, 8		// Compute (nresults+1)*8.
    937   |   beq ->fff_res			// Done if exactly 1 argument.
    938   |  li TMP1, 8
    939   |  subi RC, RC, 8
    940   |1:
    941   |  cmplw TMP1, RC
    942   |   evlddx TMP0, BASE, TMP1
    943   |   evstddx TMP0, RA, TMP1
    944   |    addi TMP1, TMP1, 8
    945   |  bne <1
    946   |  b ->fff_res
    947   |
    948   |.ffunc type
    949   |  cmplwi NARGS8:RC, 8
    950   |   lwz CARG1, 0(BASE)
    951   |  blt ->fff_fallback
    952   |    li TMP2, ~LJ_TNUMX
    953   |  cmplw CARG1, TISNUM
    954   |  not TMP1, CARG1
    955   |  isellt TMP1, TMP2, TMP1
    956   |  slwi TMP1, TMP1, 3
    957   |   la TMP2, CFUNC:RB->upvalue
    958   |  evlddx STR:CRET1, TMP2, TMP1
    959   |  b ->fff_restv
    960   |
    961   |//-- Base library: getters and setters ---------------------------------
    962   |
    963   |.ffunc_1 getmetatable
    964   |  checktab CARG1
    965   |   evmergehi TMP1, CARG1, CARG1
    966   |  checkfail >6
    967   |1:  // Field metatable must be at same offset for GCtab and GCudata!
    968   |  lwz TAB:RB, TAB:CARG1->metatable
    969   |2:
    970   |  evmr CRET1, TISNIL
    971   |   cmplwi TAB:RB, 0
    972   |  lwz STR:RC, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])(DISPATCH)
    973   |   beq ->fff_restv
    974   |  lwz TMP0, TAB:RB->hmask
    975   |   evmergelo CRET1, TISTAB, TAB:RB	// Use metatable as default result.
    976   |  lwz TMP1, STR:RC->hash
    977   |  lwz NODE:TMP2, TAB:RB->node
    978   |   evmergelo STR:RC, TISSTR, STR:RC
    979   |  and TMP1, TMP1, TMP0		// idx = str->hash & tab->hmask
    980   |  slwi TMP0, TMP1, 5
    981   |  slwi TMP1, TMP1, 3
    982   |  sub TMP1, TMP0, TMP1
    983   |  add NODE:TMP2, NODE:TMP2, TMP1	// node = tab->node + (idx*32-idx*8)
    984   |3:  // Rearranged logic, because we expect _not_ to find the key.
    985   |  evldd TMP0, NODE:TMP2->key
    986   |   evldd TMP1, NODE:TMP2->val
    987   |  evcmpeq TMP0, STR:RC
    988   |   lwz NODE:TMP2, NODE:TMP2->next
    989   |  checkallok >5
    990   |   cmplwi NODE:TMP2, 0
    991   |   beq ->fff_restv			// Not found, keep default result.
    992   |   b <3
    993   |5:
    994   |  checknil TMP1
    995   |  checkok ->fff_restv		// Ditto for nil value.
    996   |  evmr CRET1, TMP1			// Return value of mt.__metatable.
    997   |  b ->fff_restv
    998   |
    999   |6:
   1000   |  cmpwi TMP1, LJ_TUDATA
   1001   |   not TMP1, TMP1
   1002   |  beq <1
   1003   |  checknum CARG1
   1004   |   slwi TMP1, TMP1, 2
   1005   |   li TMP2, 4*~LJ_TNUMX
   1006   |  isellt TMP1, TMP2, TMP1
   1007   |   la TMP2, DISPATCH_GL(gcroot[GCROOT_BASEMT])(DISPATCH)
   1008   |  lwzx TAB:RB, TMP2, TMP1
   1009   |  b <2
   1010   |
   1011   |.ffunc_2 setmetatable
   1012   |  // Fast path: no mt for table yet and not clearing the mt.
   1013   |  evmergehi TMP0, TAB:CARG1, TAB:CARG2
   1014   |  checktab TMP0
   1015   |  checkanyfail ->fff_fallback
   1016   |  lwz TAB:TMP1, TAB:CARG1->metatable
   1017   |  cmplwi TAB:TMP1, 0
   1018   |   lbz TMP3, TAB:CARG1->marked
   1019   |  bne ->fff_fallback
   1020   |   andi. TMP0, TMP3, LJ_GC_BLACK	// isblack(table)
   1021   |    stw TAB:CARG2, TAB:CARG1->metatable
   1022   |   beq ->fff_restv
   1023   |  barrierback TAB:CARG1, TMP3, TMP0
   1024   |  b ->fff_restv
   1025   |
   1026   |.ffunc rawget
   1027   |  cmplwi NARGS8:RC, 16
   1028   |   evldd CARG2, 0(BASE)
   1029   |  blt ->fff_fallback
   1030   |  checktab CARG2
   1031   |   la CARG3, 8(BASE)
   1032   |  checkfail ->fff_fallback
   1033   |   mr CARG1, L
   1034   |  bl extern lj_tab_get  // (lua_State *L, GCtab *t, cTValue *key)
   1035   |  // Returns cTValue *.
   1036   |  evldd CRET1, 0(CRET1)
   1037   |  b ->fff_restv
   1038   |
   1039   |//-- Base library: conversions ------------------------------------------
   1040   |
   1041   |.ffunc tonumber
   1042   |  // Only handles the number case inline (without a base argument).
   1043   |  cmplwi NARGS8:RC, 8
   1044   |   evldd CARG1, 0(BASE)
   1045   |  bne ->fff_fallback			// Exactly one argument.
   1046   |  checknum CARG1
   1047   |  checkok ->fff_restv
   1048   |  b ->fff_fallback
   1049   |
   1050   |.ffunc_1 tostring
   1051   |  // Only handles the string or number case inline.
   1052   |  checkstr CARG1
   1053   |  // A __tostring method in the string base metatable is ignored.
   1054   |  checkok ->fff_restv		// String key?
   1055   |  // Handle numbers inline, unless a number base metatable is present.
   1056   |  lwz TMP0, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH)
   1057   |  checknum CARG1
   1058   |  cmplwi cr1, TMP0, 0
   1059   |   stw BASE, L->base			// Add frame since C call can throw.
   1060   |  crand 4*cr0+eq, 4*cr0+lt, 4*cr1+eq
   1061   |   stw PC, SAVE_PC			// Redundant (but a defined value).
   1062   |  bne ->fff_fallback
   1063   |  ffgccheck
   1064   |  mr CARG1, L
   1065   |  mr CARG2, BASE
   1066   |  bl extern lj_str_fromnum		// (lua_State *L, lua_Number *np)
   1067   |  // Returns GCstr *.
   1068   |  evmergelo STR:CRET1, TISSTR, STR:CRET1
   1069   |  b ->fff_restv
   1070   |
   1071   |//-- Base library: iterators -------------------------------------------
   1072   |
   1073   |.ffunc next
   1074   |  cmplwi NARGS8:RC, 8
   1075   |   evldd CARG2, 0(BASE)
   1076   |  blt ->fff_fallback
   1077   |   evstddx TISNIL, BASE, NARGS8:RC	// Set missing 2nd arg to nil.
   1078   |  checktab TAB:CARG2
   1079   |   lwz PC, FRAME_PC(BASE)
   1080   |  checkfail ->fff_fallback
   1081   |   stw BASE, L->base			// Add frame since C call can throw.
   1082   |  mr CARG1, L
   1083   |   stw BASE, L->top			// Dummy frame length is ok.
   1084   |  la CARG3, 8(BASE)
   1085   |   stw PC, SAVE_PC
   1086   |  bl extern lj_tab_next	// (lua_State *L, GCtab *t, TValue *key)
   1087   |  // Returns 0 at end of traversal.
   1088   |  cmplwi CRET1, 0
   1089   |   evmr CRET1, TISNIL
   1090   |  beq ->fff_restv			// End of traversal: return nil.
   1091   |  evldd TMP0, 8(BASE)		// Copy key and value to results.
   1092   |   la RA, -8(BASE)
   1093   |  evldd TMP1, 16(BASE)
   1094   |  evstdd TMP0, 0(RA)
   1095   |   li RD, (2+1)*8
   1096   |  evstdd TMP1, 8(RA)
   1097   |  b ->fff_res
   1098   |
   1099   |.ffunc_1 pairs
   1100   |  checktab TAB:CARG1
   1101   |   lwz PC, FRAME_PC(BASE)
   1102   |  checkfail ->fff_fallback
   1103   |   lwz TAB:TMP2, TAB:CARG1->metatable
   1104   |  evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
   1105   |   cmplwi TAB:TMP2, 0
   1106   |  la RA, -8(BASE)
   1107   |   bne ->fff_fallback
   1108   |   evstdd TISNIL, 8(BASE)
   1109   |  li RD, (3+1)*8
   1110   |  evstdd CFUNC:TMP0, 0(RA)
   1111   |  b ->fff_res
   1112   |
   1113   |.ffunc_2 ipairs_aux
   1114   |  checktab TAB:CARG1
   1115   |   lwz PC, FRAME_PC(BASE)
   1116   |  checkfail ->fff_fallback
   1117   |  checknum CARG2
   1118   |    lus TMP3, 0x3ff0
   1119   |  checkfail ->fff_fallback
   1120   |  efdctsi TMP2, CARG2
   1121   |   lwz TMP0, TAB:CARG1->asize
   1122   |    evmergelo TMP3, TMP3, ZERO
   1123   |   lwz TMP1, TAB:CARG1->array
   1124   |  efdadd CARG2, CARG2, TMP3
   1125   |  addi TMP2, TMP2, 1
   1126   |   la RA, -8(BASE)
   1127   |  cmplw TMP0, TMP2
   1128   |   slwi TMP3, TMP2, 3
   1129   |  evstdd CARG2, 0(RA)
   1130   |  ble >2				// Not in array part?
   1131   |  evlddx TMP1, TMP1, TMP3
   1132   |1:
   1133   |  checknil TMP1
   1134   |   li RD, (0+1)*8
   1135   |  checkok ->fff_res			// End of iteration, return 0 results.
   1136   |   li RD, (2+1)*8
   1137   |  evstdd TMP1, 8(RA)
   1138   |  b ->fff_res
   1139   |2:  // Check for empty hash part first. Otherwise call C function.
   1140   |  lwz TMP0, TAB:CARG1->hmask
   1141   |  cmplwi TMP0, 0
   1142   |   li RD, (0+1)*8
   1143   |  beq ->fff_res
   1144   |   mr CARG2, TMP2
   1145   |  bl extern lj_tab_getinth		// (GCtab *t, int32_t key)
   1146   |  // Returns cTValue * or NULL.
   1147   |  cmplwi CRET1, 0
   1148   |   li RD, (0+1)*8
   1149   |  beq ->fff_res
   1150   |  evldd TMP1, 0(CRET1)
   1151   |  b <1
   1152   |
   1153   |.ffunc_1 ipairs
   1154   |  checktab TAB:CARG1
   1155   |   lwz PC, FRAME_PC(BASE)
   1156   |  checkfail ->fff_fallback
   1157   |   lwz TAB:TMP2, TAB:CARG1->metatable
   1158   |  evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
   1159   |   cmplwi TAB:TMP2, 0
   1160   |  la RA, -8(BASE)
   1161   |   bne ->fff_fallback
   1162   |    evsplati TMP1, 0
   1163   |  li RD, (3+1)*8
   1164   |    evstdd TMP1, 8(BASE)
   1165   |  evstdd CFUNC:TMP0, 0(RA)
   1166   |  b ->fff_res
   1167   |
   1168   |//-- Base library: catch errors ----------------------------------------
   1169   |
   1170   |.ffunc pcall
   1171   |  cmplwi NARGS8:RC, 8
   1172   |   lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
   1173   |  blt ->fff_fallback
   1174   |   mr TMP2, BASE
   1175   |   la BASE, 8(BASE)
   1176   |  // Remember active hook before pcall.
   1177   |  rlwinm TMP3, TMP3, 32-HOOK_ACTIVE_SHIFT, 31, 31
   1178   |   subi NARGS8:RC, NARGS8:RC, 8
   1179   |  addi PC, TMP3, 8+FRAME_PCALL
   1180   |  b ->vm_call_dispatch
   1181   |
   1182   |.ffunc_2 xpcall
   1183   |  lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
   1184   |   mr TMP2, BASE
   1185   |  checkfunc CARG2			// Traceback must be a function.
   1186   |  checkfail ->fff_fallback
   1187   |   la BASE, 16(BASE)
   1188   |  // Remember active hook before pcall.
   1189   |  rlwinm TMP3, TMP3, 32-HOOK_ACTIVE_SHIFT, 31, 31
   1190   |   evstdd CARG2, 0(TMP2)		// Swap function and traceback.
   1191   |  subi NARGS8:RC, NARGS8:RC, 16
   1192   |   evstdd CARG1, 8(TMP2)
   1193   |  addi PC, TMP3, 16+FRAME_PCALL
   1194   |  b ->vm_call_dispatch
   1195   |
   1196   |//-- Coroutine library --------------------------------------------------
   1197   |
   1198   |.macro coroutine_resume_wrap, resume
   1199   |.if resume
   1200   |.ffunc_1 coroutine_resume
   1201   |  evmergehi TMP0, L:CARG1, L:CARG1
   1202   |.else
   1203   |.ffunc coroutine_wrap_aux
   1204   |  lwz L:CARG1, CFUNC:RB->upvalue[0].gcr
   1205   |.endif
   1206   |.if resume
   1207   |  cmpwi TMP0, LJ_TTHREAD
   1208   |  bne ->fff_fallback
   1209   |.endif
   1210   |  lbz TMP0, L:CARG1->status
   1211   |   lwz TMP1, L:CARG1->cframe
   1212   |    lwz CARG2, L:CARG1->top
   1213   |  cmplwi cr0, TMP0, LUA_YIELD
   1214   |    lwz TMP2, L:CARG1->base
   1215   |   cmplwi cr1, TMP1, 0
   1216   |   lwz TMP0, L:CARG1->maxstack
   1217   |    cmplw cr7, CARG2, TMP2
   1218   |   lwz PC, FRAME_PC(BASE)
   1219   |  crorc 4*cr6+lt, 4*cr0+gt, 4*cr1+eq		// st>LUA_YIELD || cframe!=0
   1220   |   add TMP2, CARG2, NARGS8:RC
   1221   |  crandc 4*cr6+gt, 4*cr7+eq, 4*cr0+eq	// base==top && st!=LUA_YIELD
   1222   |   cmplw cr1, TMP2, TMP0
   1223   |  cror 4*cr6+lt, 4*cr6+lt, 4*cr6+gt
   1224   |   stw PC, SAVE_PC
   1225   |  cror 4*cr6+lt, 4*cr6+lt, 4*cr1+gt		// cond1 || cond2 || stackov
   1226   |   stw BASE, L->base
   1227   |  blt cr6, ->fff_fallback
   1228   |1:
   1229   |.if resume
   1230   |  addi BASE, BASE, 8			// Keep resumed thread in stack for GC.
   1231   |  subi NARGS8:RC, NARGS8:RC, 8
   1232   |  subi TMP2, TMP2, 8
   1233   |.endif
   1234   |  stw TMP2, L:CARG1->top
   1235   |  li TMP1, 0
   1236   |  stw BASE, L->top
   1237   |2:  // Move args to coroutine.
   1238   |  cmpw TMP1, NARGS8:RC
   1239   |   evlddx TMP0, BASE, TMP1
   1240   |  beq >3
   1241   |   evstddx TMP0, CARG2, TMP1
   1242   |  addi TMP1, TMP1, 8
   1243   |  b <2
   1244   |3:
   1245   |  li CARG3, 0
   1246   |   mr L:SAVE0, L:CARG1
   1247   |  li CARG4, 0
   1248   |  bl ->vm_resume			// (lua_State *L, TValue *base, 0, 0)
   1249   |  // Returns thread status.
   1250   |4:
   1251   |  lwz TMP2, L:SAVE0->base
   1252   |   cmplwi CRET1, LUA_YIELD
   1253   |  lwz TMP3, L:SAVE0->top
   1254   |    li_vmstate INTERP
   1255   |  lwz BASE, L->base
   1256   |    st_vmstate
   1257   |   bgt >8
   1258   |  sub RD, TMP3, TMP2
   1259   |   lwz TMP0, L->maxstack
   1260   |  cmplwi RD, 0
   1261   |   add TMP1, BASE, RD
   1262   |  beq >6				// No results?
   1263   |  cmplw TMP1, TMP0
   1264   |   li TMP1, 0
   1265   |  bgt >9				// Need to grow stack?
   1266   |
   1267   |  subi TMP3, RD, 8
   1268   |   stw TMP2, L:SAVE0->top		// Clear coroutine stack.
   1269   |5:  // Move results from coroutine.
   1270   |  cmplw TMP1, TMP3
   1271   |   evlddx TMP0, TMP2, TMP1
   1272   |   evstddx TMP0, BASE, TMP1
   1273   |    addi TMP1, TMP1, 8
   1274   |  bne <5
   1275   |6:
   1276   |  andi. TMP0, PC, FRAME_TYPE
   1277   |.if resume
   1278   |  li TMP1, LJ_TTRUE
   1279   |   la RA, -8(BASE)
   1280   |  stw TMP1, -8(BASE)			// Prepend true to results.
   1281   |  addi RD, RD, 16
   1282   |.else
   1283   |  mr RA, BASE
   1284   |  addi RD, RD, 8
   1285   |.endif
   1286   |7:
   1287   |    stw PC, SAVE_PC
   1288   |   mr MULTRES, RD
   1289   |  beq ->BC_RET_Z
   1290   |  b ->vm_return
   1291   |
   1292   |8:  // Coroutine returned with error (at co->top-1).
   1293   |.if resume
   1294   |  andi. TMP0, PC, FRAME_TYPE
   1295   |  la TMP3, -8(TMP3)
   1296   |   li TMP1, LJ_TFALSE
   1297   |  evldd TMP0, 0(TMP3)
   1298   |   stw TMP3, L:SAVE0->top		// Remove error from coroutine stack.
   1299   |    li RD, (2+1)*8
   1300   |   stw TMP1, -8(BASE)		// Prepend false to results.
   1301   |    la RA, -8(BASE)
   1302   |  evstdd TMP0, 0(BASE)		// Copy error message.
   1303   |  b <7
   1304   |.else
   1305   |  mr CARG1, L
   1306   |  mr CARG2, L:SAVE0
   1307   |  bl extern lj_ffh_coroutine_wrap_err  // (lua_State *L, lua_State *co)
   1308   |.endif
   1309   |
   1310   |9:  // Handle stack expansion on return from yield.
   1311   |  mr CARG1, L
   1312   |  srwi CARG2, RD, 3
   1313   |  bl extern lj_state_growstack	// (lua_State *L, int n)
   1314   |  li CRET1, 0
   1315   |  b <4
   1316   |.endmacro
   1317   |
   1318   |  coroutine_resume_wrap 1		// coroutine.resume
   1319   |  coroutine_resume_wrap 0		// coroutine.wrap
   1320   |
   1321   |.ffunc coroutine_yield
   1322   |  lwz TMP0, L->cframe
   1323   |   add TMP1, BASE, NARGS8:RC
   1324   |   stw BASE, L->base
   1325   |  andi. TMP0, TMP0, CFRAME_RESUME
   1326   |   stw TMP1, L->top
   1327   |    li CRET1, LUA_YIELD
   1328   |  beq ->fff_fallback
   1329   |   stw ZERO, L->cframe
   1330   |    stb CRET1, L->status
   1331   |  b ->vm_leave_unw
   1332   |
   1333   |//-- Math library -------------------------------------------------------
   1334   |
   1335   |.ffunc_n math_abs
   1336   |  efdabs CRET1, CARG1
   1337   |  // Fallthrough.
   1338   |
   1339   |->fff_restv:
   1340   |  // CRET1 = TValue result.
   1341   |  lwz PC, FRAME_PC(BASE)
   1342   |   la RA, -8(BASE)
   1343   |  evstdd CRET1, 0(RA)
   1344   |->fff_res1:
   1345   |  // RA = results, PC = return.
   1346   |  li RD, (1+1)*8
   1347   |->fff_res:
   1348   |  // RA = results, RD = (nresults+1)*8, PC = return.
   1349   |  andi. TMP0, PC, FRAME_TYPE
   1350   |   mr MULTRES, RD
   1351   |  bne ->vm_return
   1352   |  lwz INS, -4(PC)
   1353   |  decode_RB8 RB, INS
   1354   |5:
   1355   |  cmplw RB, RD			// More results expected?
   1356   |   decode_RA8 TMP0, INS
   1357   |  bgt >6
   1358   |  ins_next1
   1359   |  // Adjust BASE. KBASE is assumed to be set for the calling frame.
   1360   |   sub BASE, RA, TMP0
   1361   |  ins_next2
   1362   |
   1363   |6:  // Fill up results with nil.
   1364   |  subi TMP1, RD, 8
   1365   |   addi RD, RD, 8
   1366   |  evstddx TISNIL, RA, TMP1
   1367   |  b <5
   1368   |
   1369   |.macro math_extern, func
   1370   |  .ffunc math_ .. func
   1371   |  cmplwi NARGS8:RC, 8
   1372   |   evldd CARG2, 0(BASE)
   1373   |  blt ->fff_fallback
   1374   |  checknum CARG2
   1375   |   evmergehi CARG1, CARG2, CARG2
   1376   |  checkfail ->fff_fallback
   1377   |  bl extern func@plt
   1378   |  evmergelo CRET1, CRET1, CRET2
   1379   |  b ->fff_restv
   1380   |.endmacro
   1381   |
   1382   |.macro math_extern2, func
   1383   |  .ffunc math_ .. func
   1384   |  cmplwi NARGS8:RC, 16
   1385   |   evldd CARG2, 0(BASE)
   1386   |   evldd CARG4, 8(BASE)
   1387   |  blt ->fff_fallback
   1388   |  evmergehi CARG1, CARG4, CARG2
   1389   |  checknum CARG1
   1390   |   evmergehi CARG3, CARG4, CARG4
   1391   |  checkanyfail ->fff_fallback
   1392   |  bl extern func@plt
   1393   |  evmergelo CRET1, CRET1, CRET2
   1394   |  b ->fff_restv
   1395   |.endmacro
   1396   |
   1397   |.macro math_round, func
   1398   |  .ffunc math_ .. func
   1399   |  cmplwi NARGS8:RC, 8
   1400   |   evldd CARG2, 0(BASE)
   1401   |  blt ->fff_fallback
   1402   |  checknum CARG2
   1403   |   evmergehi CARG1, CARG2, CARG2
   1404   |  checkfail ->fff_fallback
   1405   |   lwz PC, FRAME_PC(BASE)
   1406   |  bl ->vm_..func.._hilo;
   1407   |  la RA, -8(BASE)
   1408   |  evstdd CRET2, 0(RA)
   1409   |  b ->fff_res1
   1410   |.endmacro
   1411   |
   1412   |  math_round floor
   1413   |  math_round ceil
   1414   |
   1415   |  math_extern sqrt
   1416   |
   1417   |.ffunc math_log
   1418   |  cmplwi NARGS8:RC, 8
   1419   |   evldd CARG2, 0(BASE)
   1420   |  bne ->fff_fallback                 // Need exactly 1 argument.
   1421   |  checknum CARG2
   1422   |   evmergehi CARG1, CARG2, CARG2
   1423   |  checkfail ->fff_fallback
   1424   |  bl extern log@plt
   1425   |  evmergelo CRET1, CRET1, CRET2
   1426   |  b ->fff_restv
   1427   |
   1428   |  math_extern log10
   1429   |  math_extern exp
   1430   |  math_extern sin
   1431   |  math_extern cos
   1432   |  math_extern tan
   1433   |  math_extern asin
   1434   |  math_extern acos
   1435   |  math_extern atan
   1436   |  math_extern sinh
   1437   |  math_extern cosh
   1438   |  math_extern tanh
   1439   |  math_extern2 pow
   1440   |  math_extern2 atan2
   1441   |  math_extern2 fmod
   1442   |
   1443   |.ffunc math_ldexp
   1444   |  cmplwi NARGS8:RC, 16
   1445   |   evldd CARG2, 0(BASE)
   1446   |   evldd CARG4, 8(BASE)
   1447   |  blt ->fff_fallback
   1448   |  evmergehi CARG1, CARG4, CARG2
   1449   |  checknum CARG1
   1450   |  checkanyfail ->fff_fallback
   1451   |  efdctsi CARG3, CARG4
   1452   |  bl extern ldexp@plt
   1453   |  evmergelo CRET1, CRET1, CRET2
   1454   |  b ->fff_restv
   1455   |
   1456   |.ffunc math_frexp
   1457   |  cmplwi NARGS8:RC, 8
   1458   |   evldd CARG2, 0(BASE)
   1459   |  blt ->fff_fallback
   1460   |  checknum CARG2
   1461   |   evmergehi CARG1, CARG2, CARG2
   1462   |  checkfail ->fff_fallback
   1463   |  la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
   1464   |   lwz PC, FRAME_PC(BASE)
   1465   |  bl extern frexp@plt
   1466   |   lwz TMP1, DISPATCH_GL(tmptv)(DISPATCH)
   1467   |  evmergelo CRET1, CRET1, CRET2
   1468   |   efdcfsi CRET2, TMP1
   1469   |   la RA, -8(BASE)
   1470   |  evstdd CRET1, 0(RA)
   1471   |  li RD, (2+1)*8
   1472   |   evstdd CRET2, 8(RA)
   1473   |  b ->fff_res
   1474   |
   1475   |.ffunc math_modf
   1476   |  cmplwi NARGS8:RC, 8
   1477   |   evldd CARG2, 0(BASE)
   1478   |  blt ->fff_fallback
   1479   |  checknum CARG2
   1480   |   evmergehi CARG1, CARG2, CARG2
   1481   |  checkfail ->fff_fallback
   1482   |  la CARG3, -8(BASE)
   1483   |   lwz PC, FRAME_PC(BASE)
   1484   |  bl extern modf@plt
   1485   |  evmergelo CRET1, CRET1, CRET2
   1486   |   la RA, -8(BASE)
   1487   |  evstdd CRET1, 0(BASE)
   1488   |  li RD, (2+1)*8
   1489   |  b ->fff_res
   1490   |
   1491   |.macro math_minmax, name, cmpop
   1492   |  .ffunc_1 name
   1493   |  checknum CARG1
   1494   |   li TMP1, 8
   1495   |  checkfail ->fff_fallback
   1496   |1:
   1497   |  evlddx CARG2, BASE, TMP1
   1498   |  cmplw cr1, TMP1, NARGS8:RC
   1499   |   checknum CARG2
   1500   |  bge cr1, ->fff_restv		// Ok, since CRET1 = CARG1.
   1501   |   checkfail ->fff_fallback
   1502   |  cmpop CARG2, CARG1
   1503   |   addi TMP1, TMP1, 8
   1504   |  crmove 4*cr0+lt, 4*cr0+gt
   1505   |  evsel CARG1, CARG2, CARG1
   1506   |  b <1
   1507   |.endmacro
   1508   |
   1509   |  math_minmax math_min, efdtstlt
   1510   |  math_minmax math_max, efdtstgt
   1511   |
   1512   |//-- String library -----------------------------------------------------
   1513   |
   1514   |.ffunc_1 string_len
   1515   |  checkstr STR:CARG1
   1516   |  checkfail ->fff_fallback
   1517   |  lwz TMP0, STR:CARG1->len
   1518   |  efdcfsi CRET1, TMP0
   1519   |  b ->fff_restv
   1520   |
   1521   |.ffunc string_byte			// Only handle the 1-arg case here.
   1522   |  cmplwi NARGS8:RC, 8
   1523   |   evldd STR:CARG1, 0(BASE)
   1524   |  bne ->fff_fallback			// Need exactly 1 argument.
   1525   |  checkstr STR:CARG1
   1526   |   la RA, -8(BASE)
   1527   |  checkfail ->fff_fallback
   1528   |  lwz TMP0, STR:CARG1->len
   1529   |   li RD, (0+1)*8
   1530   |    lbz TMP1, STR:CARG1[1]		// Access is always ok (NUL at end).
   1531   |   li TMP2, (1+1)*8
   1532   |  cmplwi TMP0, 0
   1533   |   lwz PC, FRAME_PC(BASE)
   1534   |    efdcfsi CRET1, TMP1
   1535   |  iseleq RD, RD, TMP2
   1536   |    evstdd CRET1, 0(RA)
   1537   |  b ->fff_res
   1538   |
   1539   |.ffunc string_char			// Only handle the 1-arg case here.
   1540   |  ffgccheck
   1541   |  cmplwi NARGS8:RC, 8
   1542   |   evldd CARG1, 0(BASE)
   1543   |  bne ->fff_fallback			// Exactly 1 argument.
   1544   |  checknum CARG1
   1545   |   la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
   1546   |  checkfail ->fff_fallback
   1547   |  efdctsiz TMP0, CARG1
   1548   |   li CARG3, 1
   1549   |  cmplwi TMP0, 255
   1550   |   stb TMP0, 0(CARG2)
   1551   |  bgt ->fff_fallback
   1552   |->fff_newstr:
   1553   |  mr CARG1, L
   1554   |  stw BASE, L->base
   1555   |  stw PC, SAVE_PC
   1556   |  bl extern lj_str_new		// (lua_State *L, char *str, size_t l)
   1557   |  // Returns GCstr *.
   1558   |  lwz BASE, L->base
   1559   |   evmergelo STR:CRET1, TISSTR, STR:CRET1
   1560   |  b ->fff_restv
   1561   |
   1562   |.ffunc string_sub
   1563   |  ffgccheck
   1564   |  cmplwi NARGS8:RC, 16
   1565   |   evldd CARG3, 16(BASE)
   1566   |   evldd STR:CARG1, 0(BASE)
   1567   |  blt ->fff_fallback
   1568   |   evldd CARG2, 8(BASE)
   1569   |   li TMP2, -1
   1570   |  beq >1
   1571   |  checknum CARG3
   1572   |  checkfail ->fff_fallback
   1573   |  efdctsiz TMP2, CARG3
   1574   |1:
   1575   |  checknum CARG2
   1576   |  checkfail ->fff_fallback
   1577   |  checkstr STR:CARG1
   1578   |   efdctsiz TMP1, CARG2
   1579   |  checkfail ->fff_fallback
   1580   |   lwz TMP0, STR:CARG1->len
   1581   |  cmplw TMP0, TMP2			// len < end? (unsigned compare)
   1582   |   add TMP3, TMP2, TMP0
   1583   |  blt >5
   1584   |2:
   1585   |  cmpwi TMP1, 0			// start <= 0?
   1586   |   add TMP3, TMP1, TMP0
   1587   |  ble >7
   1588   |3:
   1589   |  sub. CARG3, TMP2, TMP1
   1590   |    addi CARG2, STR:CARG1, #STR-1
   1591   |   addi CARG3, CARG3, 1
   1592   |    add CARG2, CARG2, TMP1
   1593   |  isellt CARG3, r0, CARG3
   1594   |  b ->fff_newstr
   1595   |
   1596   |5:  // Negative end or overflow.
   1597   |  cmpw TMP0, TMP2
   1598   |   addi TMP3, TMP3, 1
   1599   |  iselgt TMP2, TMP3, TMP0		// end = end > len ? len : end+len+1
   1600   |  b <2
   1601   |
   1602   |7:  // Negative start or underflow.
   1603   |   cmpwi cr1, TMP3, 0
   1604   |  iseleq TMP1, r0, TMP3
   1605   |   isel TMP1, r0, TMP1, 4*cr1+lt
   1606   |  addi TMP1, TMP1, 1			// start = 1 + (start ? start+len : 0)
   1607   |  b <3
   1608   |
   1609   |.ffunc string_rep			// Only handle the 1-char case inline.
   1610   |  ffgccheck
   1611   |  cmplwi NARGS8:RC, 16
   1612   |   evldd CARG1, 0(BASE)
   1613   |   evldd CARG2, 8(BASE)
   1614   |  bne ->fff_fallback			// Exactly 2 arguments.
   1615   |  checknum CARG2
   1616   |  checkfail ->fff_fallback
   1617   |  checkstr STR:CARG1
   1618   |   efdctsiz CARG3, CARG2
   1619   |  checkfail ->fff_fallback
   1620   |   lwz TMP0, STR:CARG1->len
   1621   |  cmpwi CARG3, 0
   1622   |   lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
   1623   |  ble >2				// Count <= 0? (or non-int)
   1624   |   cmplwi TMP0, 1
   1625   |  subi TMP2, CARG3, 1
   1626   |   blt >2				// Zero length string?
   1627   |  cmplw cr1, TMP1, CARG3
   1628   |   bne ->fff_fallback		// Fallback for > 1-char strings.
   1629   |   lbz TMP0, STR:CARG1[1]
   1630   |   lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
   1631   |  blt cr1, ->fff_fallback
   1632   |1:  // Fill buffer with char. Yes, this is suboptimal code (do you care?).
   1633   |  cmplwi TMP2, 0
   1634   |   stbx TMP0, CARG2, TMP2
   1635   |   subi TMP2, TMP2, 1
   1636   |  bne <1
   1637   |  b ->fff_newstr
   1638   |2:  // Return empty string.
   1639   |  la STR:CRET1, DISPATCH_GL(strempty)(DISPATCH)
   1640   |  evmergelo CRET1, TISSTR, STR:CRET1
   1641   |  b ->fff_restv
   1642   |
   1643   |.ffunc string_reverse
   1644   |  ffgccheck
   1645   |  cmplwi NARGS8:RC, 8
   1646   |   evldd CARG1, 0(BASE)
   1647   |  blt ->fff_fallback
   1648   |  checkstr STR:CARG1
   1649   |   lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
   1650   |  checkfail ->fff_fallback
   1651   |  lwz CARG3, STR:CARG1->len
   1652   |   la CARG1, #STR(STR:CARG1)
   1653   |   lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
   1654   |   li TMP2, 0
   1655   |  cmplw TMP1, CARG3
   1656   |   subi TMP3, CARG3, 1
   1657   |  blt ->fff_fallback
   1658   |1:  // Reverse string copy.
   1659   |  cmpwi TMP3, 0
   1660   |   lbzx TMP1, CARG1, TMP2
   1661   |  blt ->fff_newstr
   1662   |   stbx TMP1, CARG2, TMP3
   1663   |  subi TMP3, TMP3, 1
   1664   |  addi TMP2, TMP2, 1
   1665   |  b <1
   1666   |
   1667   |.macro ffstring_case, name, lo
   1668   |  .ffunc name
   1669   |  ffgccheck
   1670   |  cmplwi NARGS8:RC, 8
   1671   |   evldd CARG1, 0(BASE)
   1672   |  blt ->fff_fallback
   1673   |  checkstr STR:CARG1
   1674   |   lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
   1675   |  checkfail ->fff_fallback
   1676   |  lwz CARG3, STR:CARG1->len
   1677   |   la CARG1, #STR(STR:CARG1)
   1678   |   lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
   1679   |  cmplw TMP1, CARG3
   1680   |   li TMP2, 0
   1681   |  blt ->fff_fallback
   1682   |1:  // ASCII case conversion.
   1683   |  cmplw TMP2, CARG3
   1684   |   lbzx TMP1, CARG1, TMP2
   1685   |  bge ->fff_newstr
   1686   |   subi TMP0, TMP1, lo
   1687   |    xori TMP3, TMP1, 0x20
   1688   |   cmplwi TMP0, 26
   1689   |   isellt TMP1, TMP3, TMP1
   1690   |   stbx TMP1, CARG2, TMP2
   1691   |  addi TMP2, TMP2, 1
   1692   |  b <1
   1693   |.endmacro
   1694   |
   1695   |ffstring_case string_lower, 65
   1696   |ffstring_case string_upper, 97
   1697   |
   1698   |//-- Table library ------------------------------------------------------
   1699   |
   1700   |.ffunc_1 table_getn
   1701   |  checktab CARG1
   1702   |  checkfail ->fff_fallback
   1703   |  bl extern lj_tab_len		// (GCtab *t)
   1704   |  // Returns uint32_t (but less than 2^31).
   1705   |  efdcfsi CRET1, CRET1
   1706   |  b ->fff_restv
   1707   |
   1708   |//-- Bit library --------------------------------------------------------
   1709   |
   1710   |.macro .ffunc_bit, name
   1711   |  .ffunc_n bit_..name
   1712   |  efdadd CARG1, CARG1, TOBIT
   1713   |.endmacro
   1714   |
   1715   |.ffunc_bit tobit
   1716   |->fff_resbit:
   1717   |  efdcfsi CRET1, CARG1
   1718   |  b ->fff_restv
   1719   |
   1720   |.macro .ffunc_bit_op, name, ins
   1721   |  .ffunc_bit name
   1722   |   li TMP1, 8
   1723   |1:
   1724   |  evlddx CARG2, BASE, TMP1
   1725   |  cmplw cr1, TMP1, NARGS8:RC
   1726   |   checknum CARG2
   1727   |  bge cr1, ->fff_resbit
   1728   |   checkfail ->fff_fallback
   1729   |  efdadd CARG2, CARG2, TOBIT
   1730   |  ins CARG1, CARG1, CARG2
   1731   |   addi TMP1, TMP1, 8
   1732   |  b <1
   1733   |.endmacro
   1734   |
   1735   |.ffunc_bit_op band, and
   1736   |.ffunc_bit_op bor, or
   1737   |.ffunc_bit_op bxor, xor
   1738   |
   1739   |.ffunc_bit bswap
   1740   |  rotlwi TMP0, CARG1, 8
   1741   |  rlwimi TMP0, CARG1, 24, 0, 7
   1742   |  rlwimi TMP0, CARG1, 24, 16, 23
   1743   |  efdcfsi CRET1, TMP0
   1744   |  b ->fff_restv
   1745   |
   1746   |.ffunc_bit bnot
   1747   |  not TMP0, CARG1
   1748   |  efdcfsi CRET1, TMP0
   1749   |  b ->fff_restv
   1750   |
   1751   |.macro .ffunc_bit_sh, name, ins, shmod
   1752   |  .ffunc_nn bit_..name
   1753   |  efdadd CARG2, CARG2, TOBIT
   1754   |   efdadd CARG1, CARG1, TOBIT
   1755   |.if shmod == 1
   1756   |  rlwinm CARG2, CARG2, 0, 27, 31
   1757   |.elif shmod == 2
   1758   |  neg CARG2, CARG2
   1759   |.endif
   1760   |  ins TMP0, CARG1, CARG2
   1761   |  efdcfsi CRET1, TMP0
   1762   |  b ->fff_restv
   1763   |.endmacro
   1764   |
   1765   |.ffunc_bit_sh lshift, slw, 1
   1766   |.ffunc_bit_sh rshift, srw, 1
   1767   |.ffunc_bit_sh arshift, sraw, 1
   1768   |.ffunc_bit_sh rol, rotlw, 0
   1769   |.ffunc_bit_sh ror, rotlw, 2
   1770   |
   1771   |//-----------------------------------------------------------------------
   1772   |
   1773   |->fff_fallback:			// Call fast function fallback handler.
   1774   |  // BASE = new base, RB = CFUNC, RC = nargs*8
   1775   |  lwz TMP3, CFUNC:RB->f
   1776   |    add TMP1, BASE, NARGS8:RC
   1777   |   lwz PC, FRAME_PC(BASE)		// Fallback may overwrite PC.
   1778   |    addi TMP0, TMP1, 8*LUA_MINSTACK
   1779   |     lwz TMP2, L->maxstack
   1780   |   stw PC, SAVE_PC			// Redundant (but a defined value).
   1781   |  cmplw TMP0, TMP2
   1782   |     stw BASE, L->base
   1783   |    stw TMP1, L->top
   1784   |   mr CARG1, L
   1785   |  bgt >5				// Need to grow stack.
   1786   |  mtctr TMP3
   1787   |  bctrl				// (lua_State *L)
   1788   |  // Either throws an error, or recovers and returns -1, 0 or nresults+1.
   1789   |  lwz BASE, L->base
   1790   |  cmpwi CRET1, 0
   1791   |   slwi RD, CRET1, 3
   1792   |   la RA, -8(BASE)
   1793   |  bgt ->fff_res			// Returned nresults+1?
   1794   |1:  // Returned 0 or -1: retry fast path.
   1795   |  lwz TMP0, L->top
   1796   |   lwz LFUNC:RB, FRAME_FUNC(BASE)
   1797   |  sub NARGS8:RC, TMP0, BASE
   1798   |  bne ->vm_call_tail			// Returned -1?
   1799   |  ins_callt				// Returned 0: retry fast path.
   1800   |
   1801   |// Reconstruct previous base for vmeta_call during tailcall.
   1802   |->vm_call_tail:
   1803   |  andi. TMP0, PC, FRAME_TYPE
   1804   |   rlwinm TMP1, PC, 0, 0, 28
   1805   |  bne >3
   1806   |  lwz INS, -4(PC)
   1807   |  decode_RA8 TMP1, INS
   1808   |  addi TMP1, TMP1, 8
   1809   |3:
   1810   |  sub TMP2, BASE, TMP1
   1811   |  b ->vm_call_dispatch		// Resolve again for tailcall.
   1812   |
   1813   |5:  // Grow stack for fallback handler.
   1814   |  li CARG2, LUA_MINSTACK
   1815   |  bl extern lj_state_growstack	// (lua_State *L, int n)
   1816   |  lwz BASE, L->base
   1817   |  cmpw TMP0, TMP0			// Set 4*cr0+eq to force retry.
   1818   |  b <1
   1819   |
   1820   |->fff_gcstep:			// Call GC step function.
   1821   |  // BASE = new base, RC = nargs*8
   1822   |  mflr SAVE0
   1823   |   stw BASE, L->base
   1824   |  add TMP0, BASE, NARGS8:RC
   1825   |   stw PC, SAVE_PC			// Redundant (but a defined value).
   1826   |  stw TMP0, L->top
   1827   |  mr CARG1, L
   1828   |  bl extern lj_gc_step		// (lua_State *L)
   1829   |   lwz BASE, L->base
   1830   |  mtlr SAVE0
   1831   |    lwz TMP0, L->top
   1832   |   sub NARGS8:RC, TMP0, BASE
   1833   |   lwz CFUNC:RB, FRAME_FUNC(BASE)
   1834   |  blr
   1835   |
   1836   |//-----------------------------------------------------------------------
   1837   |//-- Special dispatch targets -------------------------------------------
   1838   |//-----------------------------------------------------------------------
   1839   |
   1840   |->vm_record:				// Dispatch target for recording phase.
   1841   |.if JIT
   1842   |  NYI
   1843   |.endif
   1844   |
   1845   |->vm_rethook:			// Dispatch target for return hooks.
   1846   |  lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
   1847   |  andi. TMP0, TMP3, HOOK_ACTIVE	// Hook already active?
   1848   |  beq >1
   1849   |5:  // Re-dispatch to static ins.
   1850   |  addi TMP1, TMP1, GG_DISP2STATIC	// Assumes decode_OP4 TMP1, INS.
   1851   |  lwzx TMP0, DISPATCH, TMP1
   1852   |  mtctr TMP0
   1853   |  bctr
   1854   |
   1855   |->vm_inshook:			// Dispatch target for instr/line hooks.
   1856   |  lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
   1857   |  lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH)
   1858   |  andi. TMP0, TMP3, HOOK_ACTIVE	// Hook already active?
   1859   |   rlwinm TMP0, TMP3, 31-LUA_HOOKLINE, 31, 0
   1860   |  bne <5
   1861   |
   1862   |   cmpwi cr1, TMP0, 0
   1863   |  addic. TMP2, TMP2, -1
   1864   |   beq cr1, <5
   1865   |  stw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
   1866   |  beq >1
   1867   |   bge cr1, <5
   1868   |1:
   1869   |  mr CARG1, L
   1870   |   stw MULTRES, SAVE_MULTRES
   1871   |  mr CARG2, PC
   1872   |   stw BASE, L->base
   1873   |  // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
   1874   |  bl extern lj_dispatch_ins		// (lua_State *L, const BCIns *pc)
   1875   |3:
   1876   |  lwz BASE, L->base
   1877   |4:  // Re-dispatch to static ins.
   1878   |  lwz INS, -4(PC)
   1879   |  decode_OP4 TMP1, INS
   1880   |   decode_RB8 RB, INS
   1881   |  addi TMP1, TMP1, GG_DISP2STATIC
   1882   |   decode_RD8 RD, INS
   1883   |  lwzx TMP0, DISPATCH, TMP1
   1884   |   decode_RA8 RA, INS
   1885   |   decode_RC8 RC, INS
   1886   |  mtctr TMP0
   1887   |  bctr
   1888   |
   1889   |->cont_hook:				// Continue from hook yield.
   1890   |  addi PC, PC, 4
   1891   |  lwz MULTRES, -20(RB)		// Restore MULTRES for *M ins.
   1892   |  b <4
   1893   |
   1894   |->vm_hotloop:			// Hot loop counter underflow.
   1895   |.if JIT
   1896   |  NYI
   1897   |.endif
   1898   |
   1899   |->vm_callhook:			// Dispatch target for call hooks.
   1900   |  mr CARG2, PC
   1901   |.if JIT
   1902   |  b >1
   1903   |.endif
   1904   |
   1905   |->vm_hotcall:			// Hot call counter underflow.
   1906   |.if JIT
   1907   |  ori CARG2, PC, 1
   1908   |1:
   1909   |.endif
   1910   |  add TMP0, BASE, RC
   1911   |   stw PC, SAVE_PC
   1912   |  mr CARG1, L
   1913   |   stw BASE, L->base
   1914   |  sub RA, RA, BASE
   1915   |   stw TMP0, L->top
   1916   |  bl extern lj_dispatch_call		// (lua_State *L, const BCIns *pc)
   1917   |  // Returns ASMFunction.
   1918   |  lwz BASE, L->base
   1919   |   lwz TMP0, L->top
   1920   |   stw ZERO, SAVE_PC			// Invalidate for subsequent line hook.
   1921   |  sub NARGS8:RC, TMP0, BASE
   1922   |  add RA, BASE, RA
   1923   |  lwz LFUNC:RB, FRAME_FUNC(BASE)
   1924   |  mtctr CRET1
   1925   |  bctr
   1926   |
   1927   |//-----------------------------------------------------------------------
   1928   |//-- Trace exit handler -------------------------------------------------
   1929   |//-----------------------------------------------------------------------
   1930   |
   1931   |->vm_exit_handler:
   1932   |.if JIT
   1933   |  NYI
   1934   |.endif
   1935   |->vm_exit_interp:
   1936   |.if JIT
   1937   |  NYI
   1938   |.endif
   1939   |
   1940   |//-----------------------------------------------------------------------
   1941   |//-- Math helper functions ----------------------------------------------
   1942   |//-----------------------------------------------------------------------
   1943   |
   1944   |// FP value rounding. Called by math.floor/math.ceil fast functions
   1945   |// and from JIT code.
   1946   |//
   1947   |// This can be inlined if the CPU has the frin/friz/frip/frim instructions.
   1948   |// The alternative hard-float approaches have a deep dependency chain.
   1949   |// The resulting latency is at least 3x-7x the double-precision FP latency
   1950   |// (e500v2: 6cy, e600: 5cy, Cell: 10cy) or around 20-70 cycles.
   1951   |//
   1952   |// The soft-float approach is tedious, but much faster (e500v2: ~11cy/~6cy).
   1953   |// However it relies on a fast way to transfer the FP value to GPRs
   1954   |// (e500v2: 0cy for lo-word, 1cy for hi-word).
   1955   |//
   1956   |.macro vm_round, name, mode
   1957   |  // Used temporaries: TMP0, TMP1, TMP2, TMP3.
   1958   |->name.._efd:			// Input: CARG2, output: CRET2
   1959   |  evmergehi CARG1, CARG2, CARG2
   1960   |->name.._hilo:
   1961   |  // Input: CARG1 (hi), CARG2 (hi, lo), output: CRET2
   1962   |  rlwinm TMP2, CARG1, 12, 21, 31
   1963   |  addic. TMP2, TMP2, -1023		// exp = exponent(x) - 1023
   1964   |   li TMP1, -1
   1965   |  cmplwi cr1, TMP2, 51		// 0 <= exp <= 51?
   1966   |   subfic TMP0, TMP2, 52
   1967   |  bgt cr1, >1
   1968   |   lus TMP3, 0xfff0
   1969   |  slw TMP0, TMP1, TMP0		// lomask = -1 << (52-exp)
   1970   |   sraw TMP1, TMP3, TMP2		// himask = (int32_t)0xfff00000 >> exp
   1971   |.if mode == 2		// trunc(x):
   1972   |  evmergelo TMP0, TMP1, TMP0
   1973   |  evand CRET2, CARG2, TMP0		// hi &= himask, lo &= lomask
   1974   |.else
   1975   |  andc TMP2, CARG2, TMP0
   1976   |   andc TMP3, CARG1, TMP1
   1977   |  or TMP2, TMP2, TMP3		// ztest = (hi&~himask) | (lo&~lomask)
   1978   |   srawi TMP3, CARG1, 31		// signmask = (int32_t)hi >> 31
   1979   |.if mode == 0		// floor(x):
   1980   |  and. TMP2, TMP2, TMP3		// iszero = ((ztest & signmask) == 0)
   1981   |.else			// ceil(x):
   1982   |  andc. TMP2, TMP2, TMP3		// iszero = ((ztest & ~signmask) == 0)
   1983   |.endif
   1984   |  and CARG2, CARG2, TMP0		// lo &= lomask
   1985   |  and CARG1, CARG1, TMP1		// hi &= himask
   1986   |   subc TMP0, CARG2, TMP0
   1987   |  iseleq TMP0, CARG2, TMP0		// lo = iszero ? lo : lo-lomask
   1988   |   sube TMP1, CARG1, TMP1
   1989   |  iseleq TMP1, CARG1, TMP1		// hi = iszero ? hi : hi-himask+carry
   1990   |  evmergelo CRET2, TMP1, TMP0
   1991   |.endif
   1992   |  blr
   1993   |1:
   1994   |  bgtlr				// Already done if >=2^52, +-inf or nan.
   1995   |.if mode == 2		// trunc(x):
   1996   |  rlwinm TMP1, CARG1, 0, 0, 0	// hi = sign(x)
   1997   |  li TMP0, 0
   1998   |  evmergelo CRET2, TMP1, TMP0
   1999   |.else
   2000   |  rlwinm TMP2, CARG1, 0, 1, 31
   2001   |  srawi TMP0, CARG1, 31		// signmask = (int32_t)hi >> 31
   2002   |  or TMP2, TMP2, CARG2		// ztest = abs(hi) | lo
   2003   |   lus TMP1, 0x3ff0
   2004   |.if mode == 0		// floor(x):
   2005   |  and. TMP2, TMP2, TMP0		// iszero = ((ztest & signmask) == 0)
   2006   |.else			// ceil(x):
   2007   |  andc. TMP2, TMP2, TMP0		// iszero = ((ztest & ~signmask) == 0)
   2008   |.endif
   2009   |   li TMP0, 0
   2010   |  iseleq TMP1, r0, TMP1
   2011   |  rlwimi CARG1, TMP1, 0, 1, 31	// hi = sign(x) | (iszero ? 0.0 : 1.0)
   2012   |  evmergelo CRET2, CARG1, TMP0
   2013   |.endif
   2014   |  blr
   2015   |.endmacro
   2016   |
   2017   |->vm_floor:
   2018   |  mflr CARG3
   2019   |  evmergelo CARG2, CARG1, CARG2
   2020   |  bl ->vm_floor_hilo
   2021   |  mtlr CARG3
   2022   |  evmergehi CRET1, CRET2, CRET2
   2023   |  blr
   2024   |
   2025   |  vm_round vm_floor, 0
   2026   |  vm_round vm_ceil,  1
   2027   |.if JIT
   2028   |  vm_round vm_trunc, 2
   2029   |.else
   2030   |->vm_trunc_efd:
   2031   |->vm_trunc_hilo:
   2032   |.endif
   2033   |
   2034   |//-----------------------------------------------------------------------
   2035   |//-- Miscellaneous functions --------------------------------------------
   2036   |//-----------------------------------------------------------------------
   2037   |
   2038   |//-----------------------------------------------------------------------
   2039   |//-- FFI helper functions -----------------------------------------------
   2040   |//-----------------------------------------------------------------------
   2041   |
   2042   |->vm_ffi_call:
   2043   |.if FFI
   2044   |  NYI
   2045   |.endif
   2046   |
   2047   |//-----------------------------------------------------------------------
   2048 }
   2049 
   2050 /* Generate the code for a single instruction. */
   2051 static void build_ins(BuildCtx *ctx, BCOp op, int defop)
   2052 {
   2053   int vk = 0;
   2054   |=>defop:
   2055 
   2056   switch (op) {
   2057 
   2058   /* -- Comparison ops ---------------------------------------------------- */
   2059 
   2060   /* Remember: all ops branch for a true comparison, fall through otherwise. */
   2061 
   2062   case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
   2063     |  // RA = src1*8, RD = src2*8, JMP with RD = target
   2064     |  evlddx TMP0, BASE, RA
   2065     |   addi PC, PC, 4
   2066     |  evlddx TMP1, BASE, RD
   2067     |   addis TMP3, PC, -(BCBIAS_J*4 >> 16)
   2068     |   lwz TMP2, -4(PC)
   2069     |  evmergehi RB, TMP0, TMP1
   2070     |   decode_RD4 TMP2, TMP2
   2071     |  checknum RB
   2072     |   add TMP2, TMP2, TMP3
   2073     |  checkanyfail ->vmeta_comp
   2074     |  efdcmplt TMP0, TMP1
   2075     if (op == BC_ISLE || op == BC_ISGT) {
   2076       |  efdcmpeq cr1, TMP0, TMP1
   2077       |  cror 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
   2078     }
   2079     if (op == BC_ISLT || op == BC_ISLE) {
   2080       |  iselgt PC, TMP2, PC
   2081     } else {
   2082       |  iselgt PC, PC, TMP2
   2083     }
   2084     |  ins_next
   2085     break;
   2086 
   2087   case BC_ISEQV: case BC_ISNEV:
   2088     vk = op == BC_ISEQV;
   2089     |  // RA = src1*8, RD = src2*8, JMP with RD = target
   2090     |  evlddx CARG2, BASE, RA
   2091     |   addi PC, PC, 4
   2092     |  evlddx CARG3, BASE, RD
   2093     |   addis TMP3, PC, -(BCBIAS_J*4 >> 16)
   2094     |   lwz TMP2, -4(PC)
   2095     |  evmergehi RB, CARG2, CARG3
   2096     |   decode_RD4 TMP2, TMP2
   2097     |  checknum RB
   2098     |   add TMP2, TMP2, TMP3
   2099     |  checkanyfail >5
   2100     |  efdcmpeq CARG2, CARG3
   2101     if (vk) {
   2102       |  iselgt PC, TMP2, PC
   2103     } else {
   2104       |  iselgt PC, PC, TMP2
   2105     }
   2106     |1:
   2107     |  ins_next
   2108     |
   2109     |5:  // Either or both types are not numbers.
   2110     |  evcmpeq CARG2, CARG3
   2111     |   not TMP3, RB
   2112     |   cmplwi cr1, TMP3, ~LJ_TISPRI		// Primitive?
   2113     |  crorc 4*cr7+lt, 4*cr0+so, 4*cr0+lt	// 1: Same tv or different type.
   2114     |   cmplwi cr6, TMP3, ~LJ_TISTABUD		// Table or userdata?
   2115     |  crandc 4*cr7+gt, 4*cr0+lt, 4*cr1+gt	// 2: Same type and primitive.
   2116     |   mr SAVE0, PC
   2117     if (vk) {
   2118       |  isel PC, TMP2, PC, 4*cr7+gt
   2119     } else {
   2120       |  isel TMP2, PC, TMP2, 4*cr7+gt
   2121     }
   2122     |  cror 4*cr7+lt, 4*cr7+lt, 4*cr7+gt	// 1 or 2.
   2123     if (vk) {
   2124       |  isel PC, TMP2, PC, 4*cr0+so
   2125     } else {
   2126       |  isel PC, PC, TMP2, 4*cr0+so
   2127     }
   2128     |  blt cr7, <1			// Done if 1 or 2.
   2129     |  blt cr6, <1			// Done if not tab/ud.
   2130     |
   2131     |  // Different tables or userdatas. Need to check __eq metamethod.
   2132     |  // Field metatable must be at same offset for GCtab and GCudata!
   2133     |  lwz TAB:TMP2, TAB:CARG2->metatable
   2134     |   li CARG4, 1-vk			// ne = 0 or 1.
   2135     |  cmplwi TAB:TMP2, 0
   2136     |  beq <1				// No metatable?
   2137     |  lbz TMP2, TAB:TMP2->nomm
   2138     |  andi. TMP2, TMP2, 1<<MM_eq
   2139     |  bne <1				// Or 'no __eq' flag set?
   2140     |  mr PC, SAVE0			// Restore old PC.
   2141     |  b ->vmeta_equal			// Handle __eq metamethod.
   2142     break;
   2143 
   2144   case BC_ISEQS: case BC_ISNES:
   2145     vk = op == BC_ISEQS;
   2146     |  // RA = src*8, RD = str_const*8 (~), JMP with RD = target
   2147     |  evlddx TMP0, BASE, RA
   2148     |   srwi RD, RD, 1
   2149     |    lwz INS, 0(PC)
   2150     |   subfic RD, RD, -4
   2151     |    addi PC, PC, 4
   2152     |   lwzx STR:TMP1, KBASE, RD	// KBASE-4-str_const*4
   2153     |    addis TMP3, PC, -(BCBIAS_J*4 >> 16)
   2154     |    decode_RD4 TMP2, INS
   2155     |   evmergelo STR:TMP1, TISSTR, STR:TMP1
   2156     |    add TMP2, TMP2, TMP3
   2157     |  evcmpeq TMP0, STR:TMP1
   2158     if (vk) {
   2159       |  isel PC, TMP2, PC, 4*cr0+so
   2160     } else {
   2161       |  isel PC, PC, TMP2, 4*cr0+so
   2162     }
   2163     |  ins_next
   2164     break;
   2165 
   2166   case BC_ISEQN: case BC_ISNEN:
   2167     vk = op == BC_ISEQN;
   2168     |  // RA = src*8, RD = num_const*8, JMP with RD = target
   2169     |  evlddx TMP0, BASE, RA
   2170     |   addi PC, PC, 4
   2171     |  evlddx TMP1, KBASE, RD
   2172     |   addis TMP3, PC, -(BCBIAS_J*4 >> 16)
   2173     |   lwz INS, -4(PC)
   2174     |  checknum TMP0
   2175     |  checkfail >5
   2176     |  efdcmpeq TMP0, TMP1
   2177     |1:
   2178     |   decode_RD4 TMP2, INS
   2179     |   add TMP2, TMP2, TMP3
   2180     if (vk) {
   2181       |  iselgt PC, TMP2, PC
   2182       |5:
   2183     } else {
   2184       |  iselgt PC, PC, TMP2
   2185     }
   2186     |3:
   2187     |  ins_next
   2188     if (!vk) {
   2189       |5:
   2190       |  decode_RD4 TMP2, INS
   2191       |  add PC, TMP2, TMP3
   2192       |  b <3
   2193     }
   2194     break;
   2195 
   2196   case BC_ISEQP: case BC_ISNEP:
   2197     vk = op == BC_ISEQP;
   2198     |  // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target
   2199     |  lwzx TMP0, BASE, RA
   2200     |   srwi TMP1, RD, 3
   2201     |    lwz INS, 0(PC)
   2202     |    addi PC, PC, 4
   2203     |   not TMP1, TMP1
   2204     |    addis TMP3, PC, -(BCBIAS_J*4 >> 16)
   2205     |  cmplw TMP0, TMP1
   2206     |    decode_RD4 TMP2, INS
   2207     |    add TMP2, TMP2, TMP3
   2208     if (vk) {
   2209       |  iseleq PC, TMP2, PC
   2210     } else {
   2211       |  iseleq PC, PC, TMP2
   2212     }
   2213     |  ins_next
   2214     break;
   2215 
   2216   /* -- Unary test and copy ops ------------------------------------------- */
   2217 
   2218   case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
   2219     |  // RA = dst*8 or unused, RD = src*8, JMP with RD = target
   2220     |  evlddx TMP0, BASE, RD
   2221     |   evaddw TMP1, TISNIL, TISNIL	// Synthesize LJ_TFALSE.
   2222     |   lwz INS, 0(PC)
   2223     |  evcmpltu TMP0, TMP1
   2224     |   addi PC, PC, 4
   2225     if (op == BC_IST || op == BC_ISF) {
   2226       |  addis TMP3, PC, -(BCBIAS_J*4 >> 16)
   2227       |  decode_RD4 TMP2, INS
   2228       |  add TMP2, TMP2, TMP3
   2229       if (op == BC_IST) {
   2230 	|  isellt PC, TMP2, PC
   2231       } else {
   2232 	|  isellt PC, PC, TMP2
   2233       }
   2234     } else {
   2235       if (op == BC_ISTC) {
   2236 	|  checkfail >1
   2237       } else {
   2238 	|  checkok >1
   2239       }
   2240       |  addis PC, PC, -(BCBIAS_J*4 >> 16)
   2241       |  decode_RD4 TMP2, INS
   2242       |   evstddx TMP0, BASE, RA
   2243       |  add PC, PC, TMP2
   2244       |1:
   2245     }
   2246     |  ins_next
   2247     break;
   2248 
   2249   /* -- Unary ops --------------------------------------------------------- */
   2250 
   2251   case BC_MOV:
   2252     |  // RA = dst*8, RD = src*8
   2253     |  ins_next1
   2254     |  evlddx TMP0, BASE, RD
   2255     |  evstddx TMP0, BASE, RA
   2256     |  ins_next2
   2257     break;
   2258   case BC_NOT:
   2259     |  // RA = dst*8, RD = src*8
   2260     |  ins_next1
   2261     |  lwzx TMP0, BASE, RD
   2262     |  subfic TMP1, TMP0, LJ_TTRUE
   2263     |  adde TMP0, TMP0, TMP1
   2264     |  stwx TMP0, BASE, RA
   2265     |  ins_next2
   2266     break;
   2267   case BC_UNM:
   2268     |  // RA = dst*8, RD = src*8
   2269     |  evlddx TMP0, BASE, RD
   2270     |  checknum TMP0
   2271     |  checkfail ->vmeta_unm
   2272     |  efdneg TMP0, TMP0
   2273     |  ins_next1
   2274     |  evstddx TMP0, BASE, RA
   2275     |  ins_next2
   2276     break;
   2277   case BC_LEN:
   2278     |  // RA = dst*8, RD = src*8
   2279     |  evlddx CARG1, BASE, RD
   2280     |  checkstr CARG1
   2281     |  checkfail >2
   2282     |  lwz CRET1, STR:CARG1->len
   2283     |1:
   2284     |  ins_next1
   2285     |  efdcfsi TMP0, CRET1
   2286     |  evstddx TMP0, BASE, RA
   2287     |  ins_next2
   2288     |2:
   2289     |  checktab CARG1
   2290     |  checkfail ->vmeta_len
   2291     |  lwz TAB:TMP2, TAB:CARG1->metatable
   2292     |  cmplwi TAB:TMP2, 0
   2293     |  bne >9
   2294     |3:
   2295     |->BC_LEN_Z:
   2296     |  bl extern lj_tab_len		// (GCtab *t)
   2297     |  // Returns uint32_t (but less than 2^31).
   2298     |  b <1
   2299     |9:
   2300     |  lbz TMP0, TAB:TMP2->nomm
   2301     |  andi. TMP0, TMP0, 1<<MM_len
   2302     |  bne <3				// 'no __len' flag set: done.
   2303     |  b ->vmeta_len
   2304     break;
   2305 
   2306   /* -- Binary ops -------------------------------------------------------- */
   2307 
   2308     |.macro ins_arithpre, t0, t1
   2309     |  // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8
   2310     ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
   2311     ||switch (vk) {
   2312     ||case 0:
   2313     |   evlddx t0, BASE, RB
   2314     |    checknum t0
   2315     |   evlddx t1, KBASE, RC
   2316     |    checkfail ->vmeta_arith_vn
   2317     ||  break;
   2318     ||case 1:
   2319     |   evlddx t1, BASE, RB
   2320     |    checknum t1
   2321     |   evlddx t0, KBASE, RC
   2322     |    checkfail ->vmeta_arith_nv
   2323     ||  break;
   2324     ||default:
   2325     |   evlddx t0, BASE, RB
   2326     |   evlddx t1, BASE, RC
   2327     |    evmergehi TMP2, t0, t1
   2328     |    checknum TMP2
   2329     |    checkanyfail ->vmeta_arith_vv
   2330     ||  break;
   2331     ||}
   2332     |.endmacro
   2333     |
   2334     |.macro ins_arith, ins
   2335     |  ins_arithpre TMP0, TMP1
   2336     |  ins_next1
   2337     |  ins TMP0, TMP0, TMP1
   2338     |  evstddx TMP0, BASE, RA
   2339     |  ins_next2
   2340     |.endmacro
   2341 
   2342   case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
   2343     |  ins_arith efdadd
   2344     break;
   2345   case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
   2346     |  ins_arith efdsub
   2347     break;
   2348   case BC_MULVN: case BC_MULNV: case BC_MULVV:
   2349     |  ins_arith efdmul
   2350     break;
   2351   case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
   2352     |  ins_arith efddiv
   2353     break;
   2354   case BC_MODVN:
   2355     |  ins_arithpre RD, SAVE0
   2356     |->BC_MODVN_Z:
   2357     |  efddiv CARG2, RD, SAVE0
   2358     |  bl ->vm_floor_efd		// floor(b/c)
   2359     |  efdmul TMP0, CRET2, SAVE0
   2360     |  ins_next1
   2361     |  efdsub TMP0, RD, TMP0		// b - floor(b/c)*c
   2362     |  evstddx TMP0, BASE, RA
   2363     |  ins_next2
   2364     break;
   2365   case BC_MODNV: case BC_MODVV:
   2366     |  ins_arithpre RD, SAVE0
   2367     |  b ->BC_MODVN_Z			// Avoid 3 copies. It's slow anyway.
   2368     break;
   2369   case BC_POW:
   2370     |  evlddx CARG2, BASE, RB
   2371     |  evlddx CARG4, BASE, RC
   2372     |  evmergehi CARG1, CARG4, CARG2
   2373     |  checknum CARG1
   2374     |   evmergehi CARG3, CARG4, CARG4
   2375     |  checkanyfail ->vmeta_arith_vv
   2376     |  bl extern pow@plt
   2377     |  evmergelo CRET2, CRET1, CRET2
   2378     |  evstddx CRET2, BASE, RA
   2379     |  ins_next
   2380     break;
   2381 
   2382   case BC_CAT:
   2383     |  // RA = dst*8, RB = src_start*8, RC = src_end*8
   2384     |  sub CARG3, RC, RB
   2385     |   stw BASE, L->base
   2386     |  add CARG2, BASE, RC
   2387     |  mr SAVE0, RB
   2388     |->BC_CAT_Z:
   2389     |   stw PC, SAVE_PC
   2390     |  mr CARG1, L
   2391     |  srwi CARG3, CARG3, 3
   2392     |  bl extern lj_meta_cat		// (lua_State *L, TValue *top, int left)
   2393     |  // Returns NULL (finished) or TValue * (metamethod).
   2394     |  cmplwi CRET1, 0
   2395     |   lwz BASE, L->base
   2396     |  bne ->vmeta_binop
   2397     |  evlddx TMP0, BASE, SAVE0		// Copy result from RB to RA.
   2398     |  evstddx TMP0, BASE, RA
   2399     |  ins_next
   2400     break;
   2401 
   2402   /* -- Constant ops ------------------------------------------------------ */
   2403 
   2404   case BC_KSTR:
   2405     |  // RA = dst*8, RD = str_const*8 (~)
   2406     |  ins_next1
   2407     |  srwi TMP1, RD, 1
   2408     |  subfic TMP1, TMP1, -4
   2409     |  lwzx TMP0, KBASE, TMP1		// KBASE-4-str_const*4
   2410     |  evmergelo TMP0, TISSTR, TMP0
   2411     |  evstddx TMP0, BASE, RA
   2412     |  ins_next2
   2413     break;
   2414   case BC_KCDATA:
   2415     |.if FFI
   2416     |  // RA = dst*8, RD = cdata_const*8 (~)
   2417     |  ins_next1
   2418     |  srwi TMP1, RD, 1
   2419     |  subfic TMP1, TMP1, -4
   2420     |  lwzx TMP0, KBASE, TMP1		// KBASE-4-cdata_const*4
   2421     |  li TMP2, LJ_TCDATA
   2422     |  evmergelo TMP0, TMP2, TMP0
   2423     |  evstddx TMP0, BASE, RA
   2424     |  ins_next2
   2425     |.endif
   2426     break;
   2427   case BC_KSHORT:
   2428     |  // RA = dst*8, RD = int16_literal*8
   2429     |  srwi TMP1, RD, 3
   2430     |  extsh TMP1, TMP1
   2431     |  ins_next1
   2432     |  efdcfsi TMP0, TMP1
   2433     |  evstddx TMP0, BASE, RA
   2434     |  ins_next2
   2435     break;
   2436   case BC_KNUM:
   2437     |  // RA = dst*8, RD = num_const*8
   2438     |  evlddx TMP0, KBASE, RD
   2439     |  ins_next1
   2440     |  evstddx TMP0, BASE, RA
   2441     |  ins_next2
   2442     break;
   2443   case BC_KPRI:
   2444     |  // RA = dst*8, RD = primitive_type*8 (~)
   2445     |  srwi TMP1, RD, 3
   2446     |  not TMP0, TMP1
   2447     |  ins_next1
   2448     |  stwx TMP0, BASE, RA
   2449     |  ins_next2
   2450     break;
   2451   case BC_KNIL:
   2452     |  // RA = base*8, RD = end*8
   2453     |  evstddx TISNIL, BASE, RA
   2454     |   addi RA, RA, 8
   2455     |1:
   2456     |  evstddx TISNIL, BASE, RA
   2457     |  cmpw RA, RD
   2458     |   addi RA, RA, 8
   2459     |  blt <1
   2460     |  ins_next_
   2461     break;
   2462 
   2463   /* -- Upvalue and function ops ------------------------------------------ */
   2464 
   2465   case BC_UGET:
   2466     |  // RA = dst*8, RD = uvnum*8
   2467     |  ins_next1
   2468     |  lwz LFUNC:RB, FRAME_FUNC(BASE)
   2469     |   srwi RD, RD, 1
   2470     |   addi RD, RD, offsetof(GCfuncL, uvptr)
   2471     |  lwzx UPVAL:RB, LFUNC:RB, RD
   2472     |  lwz TMP1, UPVAL:RB->v
   2473     |  evldd TMP0, 0(TMP1)
   2474     |  evstddx TMP0, BASE, RA
   2475     |  ins_next2
   2476     break;
   2477   case BC_USETV:
   2478     |  // RA = uvnum*8, RD = src*8
   2479     |  lwz LFUNC:RB, FRAME_FUNC(BASE)
   2480     |    srwi RA, RA, 1
   2481     |    addi RA, RA, offsetof(GCfuncL, uvptr)
   2482     |   evlddx TMP1, BASE, RD
   2483     |  lwzx UPVAL:RB, LFUNC:RB, RA
   2484     |  lbz TMP3, UPVAL:RB->marked
   2485     |   lwz CARG2, UPVAL:RB->v
   2486     |  andi. TMP3, TMP3, LJ_GC_BLACK	// isblack(uv)
   2487     |    lbz TMP0, UPVAL:RB->closed
   2488     |   evmergehi TMP2, TMP1, TMP1
   2489     |   evstdd TMP1, 0(CARG2)
   2490     |    cmplwi cr1, TMP0, 0
   2491     |  cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
   2492     |   subi TMP2, TMP2, (LJ_TISNUM+1)
   2493     |  bne >2				// Upvalue is closed and black?
   2494     |1:
   2495     |  ins_next
   2496     |
   2497     |2:  // Check if new value is collectable.
   2498     |  cmplwi TMP2, LJ_TISGCV - (LJ_TISNUM+1)
   2499     |  bge <1				// tvisgcv(v)
   2500     |  lbz TMP3, GCOBJ:TMP1->gch.marked
   2501     |  andi. TMP3, TMP3, LJ_GC_WHITES	// iswhite(v)
   2502     |   la CARG1, GG_DISP2G(DISPATCH)
   2503     |  // Crossed a write barrier. Move the barrier forward.
   2504     |  beq <1
   2505     |  bl extern lj_gc_barrieruv	// (global_State *g, TValue *tv)
   2506     |  b <1
   2507     break;
   2508   case BC_USETS:
   2509     |  // RA = uvnum*8, RD = str_const*8 (~)
   2510     |  lwz LFUNC:RB, FRAME_FUNC(BASE)
   2511     |   srwi TMP1, RD, 1
   2512     |    srwi RA, RA, 1
   2513     |   subfic TMP1, TMP1, -4
   2514     |    addi RA, RA, offsetof(GCfuncL, uvptr)
   2515     |   lwzx STR:TMP1, KBASE, TMP1	// KBASE-4-str_const*4
   2516     |  lwzx UPVAL:RB, LFUNC:RB, RA
   2517     |   evmergelo STR:TMP1, TISSTR, STR:TMP1
   2518     |  lbz TMP3, UPVAL:RB->marked
   2519     |   lwz CARG2, UPVAL:RB->v
   2520     |  andi. TMP3, TMP3, LJ_GC_BLACK	// isblack(uv)
   2521     |   lbz TMP3, STR:TMP1->marked
   2522     |   lbz TMP2, UPVAL:RB->closed
   2523     |   evstdd STR:TMP1, 0(CARG2)
   2524     |  bne >2
   2525     |1:
   2526     |  ins_next
   2527     |
   2528     |2:  // Check if string is white and ensure upvalue is closed.
   2529     |  andi. TMP3, TMP3, LJ_GC_WHITES	// iswhite(str)
   2530     |   cmplwi cr1, TMP2, 0
   2531     |  cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
   2532     |   la CARG1, GG_DISP2G(DISPATCH)
   2533     |  // Crossed a write barrier. Move the barrier forward.
   2534     |  beq <1
   2535     |  bl extern lj_gc_barrieruv	// (global_State *g, TValue *tv)
   2536     |  b <1
   2537     break;
   2538   case BC_USETN:
   2539     |  // RA = uvnum*8, RD = num_const*8
   2540     |  ins_next1
   2541     |  lwz LFUNC:RB, FRAME_FUNC(BASE)
   2542     |   srwi RA, RA, 1
   2543     |   addi RA, RA, offsetof(GCfuncL, uvptr)
   2544     |    evlddx TMP0, KBASE, RD
   2545     |  lwzx UPVAL:RB, LFUNC:RB, RA
   2546     |  lwz TMP1, UPVAL:RB->v
   2547     |  evstdd TMP0, 0(TMP1)
   2548     |  ins_next2
   2549     break;
   2550   case BC_USETP:
   2551     |  // RA = uvnum*8, RD = primitive_type*8 (~)
   2552     |  ins_next1
   2553     |  lwz LFUNC:RB, FRAME_FUNC(BASE)
   2554     |   srwi RA, RA, 1
   2555     |   addi RA, RA, offsetof(GCfuncL, uvptr)
   2556     |    srwi TMP0, RD, 3
   2557     |  lwzx UPVAL:RB, LFUNC:RB, RA
   2558     |    not TMP0, TMP0
   2559     |  lwz TMP1, UPVAL:RB->v
   2560     |  stw TMP0, 0(TMP1)
   2561     |  ins_next2
   2562     break;
   2563 
   2564   case BC_UCLO:
   2565     |  // RA = level*8, RD = target
   2566     |  lwz TMP1, L->openupval
   2567     |  branch_RD			// Do this first since RD is not saved.
   2568     |   stw BASE, L->base
   2569     |  cmplwi TMP1, 0
   2570     |   mr CARG1, L
   2571     |  beq >1
   2572     |   add CARG2, BASE, RA
   2573     |  bl extern lj_func_closeuv	// (lua_State *L, TValue *level)
   2574     |  lwz BASE, L->base
   2575     |1:
   2576     |  ins_next
   2577     break;
   2578 
   2579   case BC_FNEW:
   2580     |  // RA = dst*8, RD = proto_const*8 (~) (holding function prototype)
   2581     |  srwi TMP1, RD, 1
   2582     |   stw BASE, L->base
   2583     |  subfic TMP1, TMP1, -4
   2584     |   stw PC, SAVE_PC
   2585     |  lwzx CARG2, KBASE, TMP1		// KBASE-4-tab_const*4
   2586     |   mr CARG1, L
   2587     |  lwz CARG3, FRAME_FUNC(BASE)
   2588     |  // (lua_State *L, GCproto *pt, GCfuncL *parent)
   2589     |  bl extern lj_func_newL_gc
   2590     |  // Returns GCfuncL *.
   2591     |  lwz BASE, L->base
   2592     |  evmergelo LFUNC:CRET1, TISFUNC, LFUNC:CRET1
   2593     |  evstddx LFUNC:CRET1, BASE, RA
   2594     |  ins_next
   2595     break;
   2596 
   2597   /* -- Table ops --------------------------------------------------------- */
   2598 
   2599   case BC_TNEW:
   2600   case BC_TDUP:
   2601     |  // RA = dst*8, RD = (hbits|asize)*8 | tab_const*8 (~)
   2602     |  lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
   2603     |   mr CARG1, L
   2604     |  lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
   2605     |   stw BASE, L->base
   2606     |  cmplw TMP0, TMP1
   2607     |   stw PC, SAVE_PC
   2608     |  bge >5
   2609     |1:
   2610     if (op == BC_TNEW) {
   2611       |  rlwinm CARG2, RD, 29, 21, 31
   2612       |  rlwinm CARG3, RD, 18, 27, 31
   2613       |  cmpwi CARG2, 0x7ff
   2614       |   li TMP1, 0x801
   2615       |  iseleq CARG2, TMP1, CARG2
   2616       |  bl extern lj_tab_new  // (lua_State *L, int32_t asize, uint32_t hbits)
   2617       |  // Returns Table *.
   2618     } else {
   2619       |  srwi TMP1, RD, 1
   2620       |  subfic TMP1, TMP1, -4
   2621       |  lwzx CARG2, KBASE, TMP1		// KBASE-4-tab_const*4
   2622       |  bl extern lj_tab_dup  // (lua_State *L, Table *kt)
   2623       |  // Returns Table *.
   2624     }
   2625     |  lwz BASE, L->base
   2626     |  evmergelo TAB:CRET1, TISTAB, TAB:CRET1
   2627     |  evstddx TAB:CRET1, BASE, RA
   2628     |  ins_next
   2629     |5:
   2630     |  mr SAVE0, RD
   2631     |  bl extern lj_gc_step_fixtop  // (lua_State *L)
   2632     |  mr RD, SAVE0
   2633     |  mr CARG1, L
   2634     |  b <1
   2635     break;
   2636 
   2637   case BC_GGET:
   2638     |  // RA = dst*8, RD = str_const*8 (~)
   2639   case BC_GSET:
   2640     |  // RA = src*8, RD = str_const*8 (~)
   2641     |  lwz LFUNC:TMP2, FRAME_FUNC(BASE)
   2642     |   srwi TMP1, RD, 1
   2643     |  lwz TAB:RB, LFUNC:TMP2->env
   2644     |   subfic TMP1, TMP1, -4
   2645     |   lwzx STR:RC, KBASE, TMP1	// KBASE-4-str_const*4
   2646     if (op == BC_GGET) {
   2647       |  b ->BC_TGETS_Z
   2648     } else {
   2649       |  b ->BC_TSETS_Z
   2650     }
   2651     break;
   2652 
   2653   case BC_TGETV:
   2654     |  // RA = dst*8, RB = table*8, RC = key*8
   2655     |  evlddx TAB:RB, BASE, RB
   2656     |   evlddx RC, BASE, RC
   2657     |  checktab TAB:RB
   2658     |  checkfail ->vmeta_tgetv
   2659     |  checknum RC
   2660     |  checkfail >5
   2661     |  // Convert number key to integer
   2662     |  efdctsi TMP2, RC
   2663     |   lwz TMP0, TAB:RB->asize
   2664     |  efdcfsi TMP1, TMP2
   2665     |   cmplw cr0, TMP0, TMP2
   2666     |  efdcmpeq cr1, RC, TMP1
   2667     |   lwz TMP1, TAB:RB->array
   2668     |  crand 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
   2669     |   slwi TMP2, TMP2, 3
   2670     |  ble ->vmeta_tgetv		// Integer key and in array part?
   2671     |  evlddx TMP1, TMP1, TMP2
   2672     |  checknil TMP1
   2673     |  checkok >2
   2674     |1:
   2675     |  evstddx TMP1, BASE, RA
   2676     |  ins_next
   2677     |
   2678     |2:  // Check for __index if table value is nil.
   2679     |  lwz TAB:TMP2, TAB:RB->metatable
   2680     |  cmplwi TAB:TMP2, 0
   2681     |  beq <1				// No metatable: done.
   2682     |  lbz TMP0, TAB:TMP2->nomm
   2683     |  andi. TMP0, TMP0, 1<<MM_index
   2684     |  bne <1				// 'no __index' flag set: done.
   2685     |  b ->vmeta_tgetv
   2686     |
   2687     |5:
   2688     |  checkstr STR:RC			// String key?
   2689     |  checkok ->BC_TGETS_Z
   2690     |  b ->vmeta_tgetv
   2691     break;
   2692   case BC_TGETS:
   2693     |  // RA = dst*8, RB = table*8, RC = str_const*8 (~)
   2694     |  evlddx TAB:RB, BASE, RB
   2695     |   srwi TMP1, RC, 1
   2696     |  checktab TAB:RB
   2697     |   subfic TMP1, TMP1, -4
   2698     |   lwzx STR:RC, KBASE, TMP1	// KBASE-4-str_const*4
   2699     |  checkfail ->vmeta_tgets1
   2700     |->BC_TGETS_Z:
   2701     |  // TAB:RB = GCtab *, STR:RC = GCstr *, RA = dst*8
   2702     |  lwz TMP0, TAB:RB->hmask
   2703     |  lwz TMP1, STR:RC->hash
   2704     |  lwz NODE:TMP2, TAB:RB->node
   2705     |   evmergelo STR:RC, TISSTR, STR:RC
   2706     |  and TMP1, TMP1, TMP0		// idx = str->hash & tab->hmask
   2707     |  slwi TMP0, TMP1, 5
   2708     |  slwi TMP1, TMP1, 3
   2709     |  sub TMP1, TMP0, TMP1
   2710     |  add NODE:TMP2, NODE:TMP2, TMP1	// node = tab->node + (idx*32-idx*8)
   2711     |1:
   2712     |  evldd TMP0, NODE:TMP2->key
   2713     |   evldd TMP1, NODE:TMP2->val
   2714     |  evcmpeq TMP0, STR:RC
   2715     |  checkanyfail >4
   2716     |   checknil TMP1
   2717     |   checkok >5			// Key found, but nil value?
   2718     |3:
   2719     |   evstddx TMP1, BASE, RA
   2720     |  ins_next
   2721     |
   2722     |4:  // Follow hash chain.
   2723     |  lwz NODE:TMP2, NODE:TMP2->next
   2724     |  cmplwi NODE:TMP2, 0
   2725     |  bne <1
   2726     |  // End of hash chain: key not found, nil result.
   2727     |   evmr TMP1, TISNIL
   2728     |
   2729     |5:  // Check for __index if table value is nil.
   2730     |  lwz TAB:TMP2, TAB:RB->metatable
   2731     |  cmplwi TAB:TMP2, 0
   2732     |  beq <3				// No metatable: done.
   2733     |  lbz TMP0, TAB:TMP2->nomm
   2734     |  andi. TMP0, TMP0, 1<<MM_index
   2735     |  bne <3				// 'no __index' flag set: done.
   2736     |  b ->vmeta_tgets
   2737     break;
   2738   case BC_TGETB:
   2739     |  // RA = dst*8, RB = table*8, RC = index*8
   2740     |  evlddx TAB:RB, BASE, RB
   2741     |   srwi TMP0, RC, 3
   2742     |  checktab TAB:RB
   2743     |  checkfail ->vmeta_tgetb
   2744     |  lwz TMP1, TAB:RB->asize
   2745     |   lwz TMP2, TAB:RB->array
   2746     |  cmplw TMP0, TMP1
   2747     |  bge ->vmeta_tgetb
   2748     |  evlddx TMP1, TMP2, RC
   2749     |  checknil TMP1
   2750     |  checkok >5
   2751     |1:
   2752     |  ins_next1
   2753     |  evstddx TMP1, BASE, RA
   2754     |  ins_next2
   2755     |
   2756     |5:  // Check for __index if table value is nil.
   2757     |  lwz TAB:TMP2, TAB:RB->metatable
   2758     |  cmplwi TAB:TMP2, 0
   2759     |  beq <1				// No metatable: done.
   2760     |  lbz TMP2, TAB:TMP2->nomm
   2761     |  andi. TMP2, TMP2, 1<<MM_index
   2762     |  bne <1				// 'no __index' flag set: done.
   2763     |  b ->vmeta_tgetb			// Caveat: preserve TMP0!
   2764     break;
   2765 
   2766   case BC_TSETV:
   2767     |  // RA = src*8, RB = table*8, RC = key*8
   2768     |  evlddx TAB:RB, BASE, RB
   2769     |   evlddx RC, BASE, RC
   2770     |  checktab TAB:RB
   2771     |  checkfail ->vmeta_tsetv
   2772     |  checknum RC
   2773     |  checkfail >5
   2774     |  // Convert number key to integer
   2775     |  efdctsi TMP2, RC
   2776     |    evlddx SAVE0, BASE, RA
   2777     |   lwz TMP0, TAB:RB->asize
   2778     |  efdcfsi TMP1, TMP2
   2779     |   cmplw cr0, TMP0, TMP2
   2780     |  efdcmpeq cr1, RC, TMP1
   2781     |   lwz TMP1, TAB:RB->array
   2782     |  crand 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
   2783     |   slwi TMP0, TMP2, 3
   2784     |  ble ->vmeta_tsetv		// Integer key and in array part?
   2785     |   lbz TMP3, TAB:RB->marked
   2786     |  evlddx TMP2, TMP1, TMP0
   2787     |  checknil TMP2
   2788     |  checkok >3
   2789     |1:
   2790     |  andi. TMP2, TMP3, LJ_GC_BLACK	// isblack(table)
   2791     |   evstddx SAVE0, TMP1, TMP0
   2792     |  bne >7
   2793     |2:
   2794     |  ins_next
   2795     |
   2796     |3:  // Check for __newindex if previous value is nil.
   2797     |  lwz TAB:TMP2, TAB:RB->metatable
   2798     |  cmplwi TAB:TMP2, 0
   2799     |  beq <1				// No metatable: done.
   2800     |  lbz TMP2, TAB:TMP2->nomm
   2801     |  andi. TMP2, TMP2, 1<<MM_newindex
   2802     |  bne <1				// 'no __newindex' flag set: done.
   2803     |  b ->vmeta_tsetv
   2804     |
   2805     |5:
   2806     |  checkstr STR:RC			// String key?
   2807     |  checkok ->BC_TSETS_Z
   2808     |  b ->vmeta_tsetv
   2809     |
   2810     |7:  // Possible table write barrier for the value. Skip valiswhite check.
   2811     |  barrierback TAB:RB, TMP3, TMP0
   2812     |  b <2
   2813     break;
   2814   case BC_TSETS:
   2815     |  // RA = src*8, RB = table*8, RC = str_const*8 (~)
   2816     |  evlddx TAB:RB, BASE, RB
   2817     |   srwi TMP1, RC, 1
   2818     |  checktab TAB:RB
   2819     |   subfic TMP1, TMP1, -4
   2820     |   lwzx STR:RC, KBASE, TMP1	// KBASE-4-str_const*4
   2821     |  checkfail ->vmeta_tsets1
   2822     |->BC_TSETS_Z:
   2823     |  // TAB:RB = GCtab *, STR:RC = GCstr *, RA = src*8
   2824     |  lwz TMP0, TAB:RB->hmask
   2825     |  lwz TMP1, STR:RC->hash
   2826     |  lwz NODE:TMP2, TAB:RB->node
   2827     |   evmergelo STR:RC, TISSTR, STR:RC
   2828     |    stb ZERO, TAB:RB->nomm		// Clear metamethod cache.
   2829     |  and TMP1, TMP1, TMP0		// idx = str->hash & tab->hmask
   2830     |    evlddx SAVE0, BASE, RA
   2831     |  slwi TMP0, TMP1, 5
   2832     |  slwi TMP1, TMP1, 3
   2833     |  sub TMP1, TMP0, TMP1
   2834     |    lbz TMP3, TAB:RB->marked
   2835     |  add NODE:TMP2, NODE:TMP2, TMP1	// node = tab->node + (idx*32-idx*8)
   2836     |1:
   2837     |  evldd TMP0, NODE:TMP2->key
   2838     |   evldd TMP1, NODE:TMP2->val
   2839     |  evcmpeq TMP0, STR:RC
   2840     |  checkanyfail >5
   2841     |   checknil TMP1
   2842     |   checkok >4			// Key found, but nil value?
   2843     |2:
   2844     |  andi. TMP0, TMP3, LJ_GC_BLACK	// isblack(table)
   2845     |    evstdd SAVE0, NODE:TMP2->val
   2846     |  bne >7
   2847     |3:
   2848     |  ins_next
   2849     |
   2850     |4:  // Check for __newindex if previous value is nil.
   2851     |  lwz TAB:TMP1, TAB:RB->metatable
   2852     |  cmplwi TAB:TMP1, 0
   2853     |  beq <2				// No metatable: done.
   2854     |  lbz TMP0, TAB:TMP1->nomm
   2855     |  andi. TMP0, TMP0, 1<<MM_newindex
   2856     |  bne <2				// 'no __newindex' flag set: done.
   2857     |  b ->vmeta_tsets
   2858     |
   2859     |5:  // Follow hash chain.
   2860     |  lwz NODE:TMP2, NODE:TMP2->next
   2861     |  cmplwi NODE:TMP2, 0
   2862     |  bne <1
   2863     |  // End of hash chain: key not found, add a new one.
   2864     |
   2865     |  // But check for __newindex first.
   2866     |  lwz TAB:TMP1, TAB:RB->metatable
   2867     |   la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
   2868     |   stw PC, SAVE_PC
   2869     |   mr CARG1, L
   2870     |  cmplwi TAB:TMP1, 0
   2871     |   stw BASE, L->base
   2872     |  beq >6				// No metatable: continue.
   2873     |  lbz TMP0, TAB:TMP1->nomm
   2874     |  andi. TMP0, TMP0, 1<<MM_newindex
   2875     |  beq ->vmeta_tsets		// 'no __newindex' flag NOT set: check.
   2876     |6:
   2877     |  mr CARG2, TAB:RB
   2878     |  evstdd STR:RC, 0(CARG3)
   2879     |  bl extern lj_tab_newkey		// (lua_State *L, GCtab *t, TValue *k)
   2880     |  // Returns TValue *.
   2881     |  lwz BASE, L->base
   2882     |  evstdd SAVE0, 0(CRET1)
   2883     |  b <3				// No 2nd write barrier needed.
   2884     |
   2885     |7:  // Possible table write barrier for the value. Skip valiswhite check.
   2886     |  barrierback TAB:RB, TMP3, TMP0
   2887     |  b <3
   2888     break;
   2889   case BC_TSETB:
   2890     |  // RA = src*8, RB = table*8, RC = index*8
   2891     |  evlddx TAB:RB, BASE, RB
   2892     |   srwi TMP0, RC, 3
   2893     |  checktab TAB:RB
   2894     |  checkfail ->vmeta_tsetb
   2895     |  lwz TMP1, TAB:RB->asize
   2896     |   lwz TMP2, TAB:RB->array
   2897     |    lbz TMP3, TAB:RB->marked
   2898     |  cmplw TMP0, TMP1
   2899     |   evlddx SAVE0, BASE, RA
   2900     |  bge ->vmeta_tsetb
   2901     |  evlddx TMP1, TMP2, RC
   2902     |  checknil TMP1
   2903     |  checkok >5
   2904     |1:
   2905     |  andi. TMP0, TMP3, LJ_GC_BLACK	// isblack(table)
   2906     |   evstddx SAVE0, TMP2, RC
   2907     |  bne >7
   2908     |2:
   2909     |  ins_next
   2910     |
   2911     |5:  // Check for __newindex if previous value is nil.
   2912     |  lwz TAB:TMP1, TAB:RB->metatable
   2913     |  cmplwi TAB:TMP1, 0
   2914     |  beq <1				// No metatable: done.
   2915     |  lbz TMP1, TAB:TMP1->nomm
   2916     |  andi. TMP1, TMP1, 1<<MM_newindex
   2917     |  bne <1				// 'no __newindex' flag set: done.
   2918     |  b ->vmeta_tsetb			// Caveat: preserve TMP0!
   2919     |
   2920     |7:  // Possible table write barrier for the value. Skip valiswhite check.
   2921     |  barrierback TAB:RB, TMP3, TMP0
   2922     |  b <2
   2923     break;
   2924 
   2925   case BC_TSETM:
   2926     |  // RA = base*8 (table at base-1), RD = num_const*8 (start index)
   2927     |  add RA, BASE, RA
   2928     |1:
   2929     |   add TMP3, KBASE, RD
   2930     |  lwz TAB:CARG2, -4(RA)		// Guaranteed to be a table.
   2931     |    addic. TMP0, MULTRES, -8
   2932     |   lwz TMP3, 4(TMP3)		// Integer constant is in lo-word.
   2933     |    srwi CARG3, TMP0, 3
   2934     |    beq >4				// Nothing to copy?
   2935     |  add CARG3, CARG3, TMP3
   2936     |  lwz TMP2, TAB:CARG2->asize
   2937     |   slwi TMP1, TMP3, 3
   2938     |    lbz TMP3, TAB:CARG2->marked
   2939     |  cmplw CARG3, TMP2
   2940     |   add TMP2, RA, TMP0
   2941     |   lwz TMP0, TAB:CARG2->array
   2942     |  bgt >5
   2943     |   add TMP1, TMP1, TMP0
   2944     |    andi. TMP0, TMP3, LJ_GC_BLACK	// isblack(table)
   2945     |3:  // Copy result slots to table.
   2946     |   evldd TMP0, 0(RA)
   2947     |  addi RA, RA, 8
   2948     |  cmpw cr1, RA, TMP2
   2949     |   evstdd TMP0, 0(TMP1)
   2950     |    addi TMP1, TMP1, 8
   2951     |  blt cr1, <3
   2952     |  bne >7
   2953     |4:
   2954     |  ins_next
   2955     |
   2956     |5:  // Need to resize array part.
   2957     |   stw BASE, L->base
   2958     |  mr CARG1, L
   2959     |   stw PC, SAVE_PC
   2960     |  mr SAVE0, RD
   2961     |  bl extern lj_tab_reasize		// (lua_State *L, GCtab *t, int nasize)
   2962     |  // Must not reallocate the stack.
   2963     |  mr RD, SAVE0
   2964     |  b <1
   2965     |
   2966     |7:  // Possible table write barrier for any value. Skip valiswhite check.
   2967     |  barrierback TAB:CARG2, TMP3, TMP0
   2968     |  b <4
   2969     break;
   2970 
   2971   /* -- Calls and vararg handling ----------------------------------------- */
   2972 
   2973   case BC_CALLM:
   2974     |  // RA = base*8, (RB = (nresults+1)*8,) RC = extra_nargs*8
   2975     |  add NARGS8:RC, NARGS8:RC, MULTRES
   2976     |  // Fall through. Assumes BC_CALL follows.
   2977     break;
   2978   case BC_CALL:
   2979     |  // RA = base*8, (RB = (nresults+1)*8,) RC = (nargs+1)*8
   2980     |  evlddx LFUNC:RB, BASE, RA
   2981     |   mr TMP2, BASE
   2982     |   add BASE, BASE, RA
   2983     |    subi NARGS8:RC, NARGS8:RC, 8
   2984     |  checkfunc LFUNC:RB
   2985     |   addi BASE, BASE, 8
   2986     |  checkfail ->vmeta_call
   2987     |  ins_call
   2988     break;
   2989 
   2990   case BC_CALLMT:
   2991     |  // RA = base*8, (RB = 0,) RC = extra_nargs*8
   2992     |  add NARGS8:RC, NARGS8:RC, MULTRES
   2993     |  // Fall through. Assumes BC_CALLT follows.
   2994     break;
   2995   case BC_CALLT:
   2996     |  // RA = base*8, (RB = 0,) RC = (nargs+1)*8
   2997     |  evlddx LFUNC:RB, BASE, RA
   2998     |   add RA, BASE, RA
   2999     |    lwz TMP1, FRAME_PC(BASE)
   3000     |    subi NARGS8:RC, NARGS8:RC, 8
   3001     |  checkfunc LFUNC:RB
   3002     |   addi RA, RA, 8
   3003     |  checkfail ->vmeta_callt
   3004     |->BC_CALLT_Z:
   3005     |  andi. TMP0, TMP1, FRAME_TYPE	// Caveat: preserve cr0 until the crand.
   3006     |   lbz TMP3, LFUNC:RB->ffid
   3007     |    xori TMP2, TMP1, FRAME_VARG
   3008     |    cmplwi cr1, NARGS8:RC, 0
   3009     |  bne >7
   3010     |1:
   3011     |  stw LFUNC:RB, FRAME_FUNC(BASE)	// Copy function down, but keep PC.
   3012     |  li TMP2, 0
   3013     |   cmplwi cr7, TMP3, 1		// (> FF_C) Calling a fast function?
   3014     |    beq cr1, >3
   3015     |2:
   3016     |  addi TMP3, TMP2, 8
   3017     |   evlddx TMP0, RA, TMP2
   3018     |  cmplw cr1, TMP3, NARGS8:RC
   3019     |   evstddx TMP0, BASE, TMP2
   3020     |  mr TMP2, TMP3
   3021     |  bne cr1, <2
   3022     |3:
   3023     |  crand 4*cr0+eq, 4*cr0+eq, 4*cr7+gt
   3024     |  beq >5
   3025     |4:
   3026     |  ins_callt
   3027     |
   3028     |5:  // Tailcall to a fast function with a Lua frame below.
   3029     |  lwz INS, -4(TMP1)
   3030     |  decode_RA8 RA, INS
   3031     |  sub TMP1, BASE, RA
   3032     |  lwz LFUNC:TMP1, FRAME_FUNC-8(TMP1)
   3033     |  lwz TMP1, LFUNC:TMP1->pc
   3034     |  lwz KBASE, PC2PROTO(k)(TMP1)	// Need to prepare KBASE.
   3035     |  b <4
   3036     |
   3037     |7:  // Tailcall from a vararg function.
   3038     |  andi. TMP0, TMP2, FRAME_TYPEP
   3039     |  bne <1				// Vararg frame below?
   3040     |  sub BASE, BASE, TMP2		// Relocate BASE down.
   3041     |  lwz TMP1, FRAME_PC(BASE)
   3042     |  andi. TMP0, TMP1, FRAME_TYPE
   3043     |  b <1
   3044     break;
   3045 
   3046   case BC_ITERC:
   3047     |  // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 ((2+1)*8))
   3048     |  subi RA, RA, 24			// evldd doesn't support neg. offsets.
   3049     |   mr TMP2, BASE
   3050     |  evlddx LFUNC:RB, BASE, RA
   3051     |   add BASE, BASE, RA
   3052     |   evldd TMP0, 8(BASE)
   3053     |    evldd TMP1, 16(BASE)
   3054     |  evstdd LFUNC:RB, 24(BASE)	// Copy callable.
   3055     |  checkfunc LFUNC:RB
   3056     |   evstdd TMP0, 32(BASE)		// Copy state.
   3057     |     li NARGS8:RC, 16		// Iterators get 2 arguments.
   3058     |    evstdd TMP1, 40(BASE)		// Copy control var.
   3059     |     addi BASE, BASE, 32
   3060     |  checkfail ->vmeta_call
   3061     |  ins_call
   3062     break;
   3063 
   3064   case BC_ITERN:
   3065     |  // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 (2+1)*8)
   3066     |.if JIT
   3067     |  // NYI: add hotloop, record BC_ITERN.
   3068     |.endif
   3069     |  add RA, BASE, RA
   3070     |  lwz TAB:RB, -12(RA)
   3071     |  lwz RC, -4(RA)			// Get index from control var.
   3072     |  lwz TMP0, TAB:RB->asize
   3073     |  lwz TMP1, TAB:RB->array
   3074     |   addi PC, PC, 4
   3075     |1:  // Traverse array part.
   3076     |  cmplw RC, TMP0
   3077     |   slwi TMP3, RC, 3
   3078     |  bge >5				// Index points after array part?
   3079     |  evlddx TMP2, TMP1, TMP3
   3080     |  checknil TMP2
   3081     |     lwz INS, -4(PC)
   3082     |  checkok >4
   3083     |   efdcfsi TMP0, RC
   3084     |    addi RC, RC, 1
   3085     |     addis TMP3, PC, -(BCBIAS_J*4 >> 16)
   3086     |  evstdd TMP2, 8(RA)
   3087     |     decode_RD4 TMP1, INS
   3088     |    stw RC, -4(RA)			// Update control var.
   3089     |     add PC, TMP1, TMP3
   3090     |   evstdd TMP0, 0(RA)
   3091     |3:
   3092     |  ins_next
   3093     |
   3094     |4:  // Skip holes in array part.
   3095     |  addi RC, RC, 1
   3096     |  b <1
   3097     |
   3098     |5:  // Traverse hash part.
   3099     |  lwz TMP1, TAB:RB->hmask
   3100     |  sub RC, RC, TMP0
   3101     |   lwz TMP2, TAB:RB->node
   3102     |6:
   3103     |  cmplw RC, TMP1			// End of iteration? Branch to ITERL+1.
   3104     |   slwi TMP3, RC, 5
   3105     |  bgt <3
   3106     |   slwi RB, RC, 3
   3107     |   sub TMP3, TMP3, RB
   3108     |  evlddx RB, TMP2, TMP3
   3109     |   add NODE:TMP3, TMP2, TMP3
   3110     |  checknil RB
   3111     |     lwz INS, -4(PC)
   3112     |  checkok >7
   3113     |   evldd TMP3, NODE:TMP3->key
   3114     |     addis TMP2, PC, -(BCBIAS_J*4 >> 16)
   3115     |  evstdd RB, 8(RA)
   3116     |    add RC, RC, TMP0
   3117     |     decode_RD4 TMP1, INS
   3118     |   evstdd TMP3, 0(RA)
   3119     |    addi RC, RC, 1
   3120     |     add PC, TMP1, TMP2
   3121     |    stw RC, -4(RA)			// Update control var.
   3122     |  b <3
   3123     |
   3124     |7:  // Skip holes in hash part.
   3125     |  addi RC, RC, 1
   3126     |  b <6
   3127     break;
   3128 
   3129   case BC_ISNEXT:
   3130     |  // RA = base*8, RD = target (points to ITERN)
   3131     |  add RA, BASE, RA
   3132     |   li TMP2, -24
   3133     |  evlddx CFUNC:TMP1, RA, TMP2
   3134     |   lwz TMP2, -16(RA)
   3135     |    lwz TMP3, -8(RA)
   3136     |  evmergehi TMP0, CFUNC:TMP1, CFUNC:TMP1
   3137     |   cmpwi cr0, TMP2, LJ_TTAB
   3138     |  cmpwi cr1, TMP0, LJ_TFUNC
   3139     |    cmpwi cr6, TMP3, LJ_TNIL
   3140     |  bne cr1, >5
   3141     |  lbz TMP1, CFUNC:TMP1->ffid
   3142     |   crand 4*cr0+eq, 4*cr0+eq, 4*cr6+eq
   3143     |  cmpwi cr7, TMP1, FF_next_N
   3144     |    srwi TMP0, RD, 1
   3145     |  crand 4*cr0+eq, 4*cr0+eq, 4*cr7+eq
   3146     |    add TMP3, PC, TMP0
   3147     |  bne cr0, >5
   3148     |  lus TMP1, 0xfffe
   3149     |  ori TMP1, TMP1, 0x7fff
   3150     |  stw ZERO, -4(RA)			// Initialize control var.
   3151     |  stw TMP1, -8(RA)
   3152     |    addis PC, TMP3, -(BCBIAS_J*4 >> 16)
   3153     |1:
   3154     |  ins_next
   3155     |5:  // Despecialize bytecode if any of the checks fail.
   3156     |  li TMP0, BC_JMP
   3157     |   li TMP1, BC_ITERC
   3158     |  stb TMP0, -1(PC)
   3159     |    addis PC, TMP3, -(BCBIAS_J*4 >> 16)
   3160     |   stb TMP1, 3(PC)
   3161     |  b <1
   3162     break;
   3163 
   3164   case BC_VARG:
   3165     |  // RA = base*8, RB = (nresults+1)*8, RC = numparams*8
   3166     |  lwz TMP0, FRAME_PC(BASE)
   3167     |  add RC, BASE, RC
   3168     |   add RA, BASE, RA
   3169     |  addi RC, RC, FRAME_VARG
   3170     |   add TMP2, RA, RB
   3171     |  subi TMP3, BASE, 8		// TMP3 = vtop
   3172     |  sub RC, RC, TMP0			// RC = vbase
   3173     |  // Note: RC may now be even _above_ BASE if nargs was < numparams.
   3174     |  cmplwi cr1, RB, 0
   3175     |   sub. TMP1, TMP3, RC
   3176     |  beq cr1, >5			// Copy all varargs?
   3177     |   subi TMP2, TMP2, 16
   3178     |   ble >2				// No vararg slots?
   3179     |1:  // Copy vararg slots to destination slots.
   3180     |  evldd TMP0, 0(RC)
   3181     |   addi RC, RC, 8
   3182     |  evstdd TMP0, 0(RA)
   3183     |  cmplw RA, TMP2
   3184     |   cmplw cr1, RC, TMP3
   3185     |  bge >3				// All destination slots filled?
   3186     |    addi RA, RA, 8
   3187     |   blt cr1, <1			// More vararg slots?
   3188     |2:  // Fill up remainder with nil.
   3189     |  evstdd TISNIL, 0(RA)
   3190     |  cmplw RA, TMP2
   3191     |   addi RA, RA, 8
   3192     |  blt <2
   3193     |3:
   3194     |  ins_next
   3195     |
   3196     |5:  // Copy all varargs.
   3197     |  lwz TMP0, L->maxstack
   3198     |   li MULTRES, 8			// MULTRES = (0+1)*8
   3199     |  ble <3				// No vararg slots?
   3200     |  add TMP2, RA, TMP1
   3201     |  cmplw TMP2, TMP0
   3202     |   addi MULTRES, TMP1, 8
   3203     |  bgt >7
   3204     |6:
   3205     |  evldd TMP0, 0(RC)
   3206     |   addi RC, RC, 8
   3207     |  evstdd TMP0, 0(RA)
   3208     |  cmplw RC, TMP3
   3209     |   addi RA, RA, 8
   3210     |  blt <6				// More vararg slots?
   3211     |  b <3
   3212     |
   3213     |7:  // Grow stack for varargs.
   3214     |  mr CARG1, L
   3215     |   stw RA, L->top
   3216     |  sub SAVE0, RC, BASE		// Need delta, because BASE may change.
   3217     |   stw BASE, L->base
   3218     |  sub RA, RA, BASE
   3219     |   stw PC, SAVE_PC
   3220     |  srwi CARG2, TMP1, 3
   3221     |  bl extern lj_state_growstack	// (lua_State *L, int n)
   3222     |  lwz BASE, L->base
   3223     |  add RA, BASE, RA
   3224     |  add RC, BASE, SAVE0
   3225     |  subi TMP3, BASE, 8
   3226     |  b <6
   3227     break;
   3228 
   3229   /* -- Returns ----------------------------------------------------------- */
   3230 
   3231   case BC_RETM:
   3232     |  // RA = results*8, RD = extra_nresults*8
   3233     |  add RD, RD, MULTRES		// MULTRES >= 8, so RD >= 8.
   3234     |  // Fall through. Assumes BC_RET follows.
   3235     break;
   3236 
   3237   case BC_RET:
   3238     |  // RA = results*8, RD = (nresults+1)*8
   3239     |  lwz PC, FRAME_PC(BASE)
   3240     |   add RA, BASE, RA
   3241     |    mr MULTRES, RD
   3242     |1:
   3243     |  andi. TMP0, PC, FRAME_TYPE
   3244     |   xori TMP1, PC, FRAME_VARG
   3245     |  bne ->BC_RETV_Z
   3246     |
   3247     |->BC_RET_Z:
   3248     |  // BASE = base, RA = resultptr, RD = (nresults+1)*8, PC = return
   3249     |   lwz INS, -4(PC)
   3250     |  cmpwi RD, 8
   3251     |   subi TMP2, BASE, 8
   3252     |   subi RC, RD, 8
   3253     |   decode_RB8 RB, INS
   3254     |  beq >3
   3255     |   li TMP1, 0
   3256     |2:
   3257     |  addi TMP3, TMP1, 8
   3258     |   evlddx TMP0, RA, TMP1
   3259     |  cmpw TMP3, RC
   3260     |   evstddx TMP0, TMP2, TMP1
   3261     |  beq >3
   3262     |  addi TMP1, TMP3, 8
   3263     |   evlddx TMP0, RA, TMP3
   3264     |  cmpw TMP1, RC
   3265     |   evstddx TMP0, TMP2, TMP3
   3266     |  bne <2
   3267     |3:
   3268     |5:
   3269     |  cmplw RB, RD
   3270     |   decode_RA8 RA, INS
   3271     |  bgt >6
   3272     |   sub BASE, TMP2, RA
   3273     |  lwz LFUNC:TMP1, FRAME_FUNC(BASE)
   3274     |  ins_next1
   3275     |  lwz TMP1, LFUNC:TMP1->pc
   3276     |  lwz KBASE, PC2PROTO(k)(TMP1)
   3277     |  ins_next2
   3278     |
   3279     |6:  // Fill up results with nil.
   3280     |  subi TMP1, RD, 8
   3281     |   addi RD, RD, 8
   3282     |  evstddx TISNIL, TMP2, TMP1
   3283     |  b <5
   3284     |
   3285     |->BC_RETV_Z:  // Non-standard return case.
   3286     |  andi. TMP2, TMP1, FRAME_TYPEP
   3287     |  bne ->vm_return
   3288     |  // Return from vararg function: relocate BASE down.
   3289     |  sub BASE, BASE, TMP1
   3290     |  lwz PC, FRAME_PC(BASE)
   3291     |  b <1
   3292     break;
   3293 
   3294   case BC_RET0: case BC_RET1:
   3295     |  // RA = results*8, RD = (nresults+1)*8
   3296     |  lwz PC, FRAME_PC(BASE)
   3297     |   add RA, BASE, RA
   3298     |    mr MULTRES, RD
   3299     |  andi. TMP0, PC, FRAME_TYPE
   3300     |   xori TMP1, PC, FRAME_VARG
   3301     |  bne ->BC_RETV_Z
   3302     |
   3303     |  lwz INS, -4(PC)
   3304     |   subi TMP2, BASE, 8
   3305     |  decode_RB8 RB, INS
   3306     if (op == BC_RET1) {
   3307       |  evldd TMP0, 0(RA)
   3308       |  evstdd TMP0, 0(TMP2)
   3309     }
   3310     |5:
   3311     |  cmplw RB, RD
   3312     |   decode_RA8 RA, INS
   3313     |  bgt >6
   3314     |   sub BASE, TMP2, RA
   3315     |  lwz LFUNC:TMP1, FRAME_FUNC(BASE)
   3316     |  ins_next1
   3317     |  lwz TMP1, LFUNC:TMP1->pc
   3318     |  lwz KBASE, PC2PROTO(k)(TMP1)
   3319     |  ins_next2
   3320     |
   3321     |6:  // Fill up results with nil.
   3322     |  subi TMP1, RD, 8
   3323     |   addi RD, RD, 8
   3324     |  evstddx TISNIL, TMP2, TMP1
   3325     |  b <5
   3326     break;
   3327 
   3328   /* -- Loops and branches ------------------------------------------------ */
   3329 
   3330   case BC_FORL:
   3331     |.if JIT
   3332     |  hotloop
   3333     |.endif
   3334     |  // Fall through. Assumes BC_IFORL follows.
   3335     break;
   3336 
   3337   case BC_JFORI:
   3338   case BC_JFORL:
   3339 #if !LJ_HASJIT
   3340     break;
   3341 #endif
   3342   case BC_FORI:
   3343   case BC_IFORL:
   3344     |  // RA = base*8, RD = target (after end of loop or start of loop)
   3345     vk = (op == BC_IFORL || op == BC_JFORL);
   3346     |  add RA, BASE, RA
   3347     |  evldd TMP1, FORL_IDX*8(RA)
   3348     |  evldd TMP3, FORL_STEP*8(RA)
   3349     |  evldd TMP2, FORL_STOP*8(RA)
   3350     if (!vk) {
   3351       |  evcmpgtu cr0, TMP1, TISNUM
   3352       |  evcmpgtu cr7, TMP3, TISNUM
   3353       |  evcmpgtu cr1, TMP2, TISNUM
   3354       |  cror 4*cr0+lt, 4*cr0+lt, 4*cr7+lt
   3355       |  cror 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
   3356       |  blt ->vmeta_for
   3357     }
   3358     if (vk) {
   3359       |  efdadd TMP1, TMP1, TMP3
   3360       |  evstdd TMP1, FORL_IDX*8(RA)
   3361     }
   3362     |   evcmpgts TMP3, TISNIL
   3363     |  evstdd TMP1, FORL_EXT*8(RA)
   3364     |   bge >2
   3365     |  efdcmpgt TMP1, TMP2
   3366     |1:
   3367     if (op != BC_JFORL) {
   3368       |  srwi RD, RD, 1
   3369       |  add RD, PC, RD
   3370       if (op == BC_JFORI) {
   3371 	|  addis PC, RD, -(BCBIAS_J*4 >> 16)
   3372       } else {
   3373 	|  addis RD, RD, -(BCBIAS_J*4 >> 16)
   3374       }
   3375     }
   3376     if (op == BC_FORI) {
   3377       |  iselgt PC, RD, PC
   3378     } else if (op == BC_IFORL) {
   3379       |  iselgt PC, PC, RD
   3380     } else {
   3381       |  ble =>BC_JLOOP
   3382     }
   3383     |  ins_next
   3384     |2:
   3385     |  efdcmpgt TMP2, TMP1
   3386     |  b <1
   3387     break;
   3388 
   3389   case BC_ITERL:
   3390     |.if JIT
   3391     |  hotloop
   3392     |.endif
   3393     |  // Fall through. Assumes BC_IITERL follows.
   3394     break;
   3395 
   3396   case BC_JITERL:
   3397 #if !LJ_HASJIT
   3398     break;
   3399 #endif
   3400   case BC_IITERL:
   3401     |  // RA = base*8, RD = target
   3402     |  evlddx TMP1, BASE, RA
   3403     |   subi RA, RA, 8
   3404     |  checknil TMP1
   3405     |  checkok >1			// Stop if iterator returned nil.
   3406     if (op == BC_JITERL) {
   3407       |  NYI
   3408     } else {
   3409       |  branch_RD			// Otherwise save control var + branch.
   3410       |  evstddx TMP1, BASE, RA
   3411     }
   3412     |1:
   3413     |  ins_next
   3414     break;
   3415 
   3416   case BC_LOOP:
   3417     |  // RA = base*8, RD = target (loop extent)
   3418     |  // Note: RA/RD is only used by trace recorder to determine scope/extent
   3419     |  // This opcode does NOT jump, it's only purpose is to detect a hot loop.
   3420     |.if JIT
   3421     |  hotloop
   3422     |.endif
   3423     |  // Fall through. Assumes BC_ILOOP follows.
   3424     break;
   3425 
   3426   case BC_ILOOP:
   3427     |  // RA = base*8, RD = target (loop extent)
   3428     |  ins_next
   3429     break;
   3430 
   3431   case BC_JLOOP:
   3432     |.if JIT
   3433     |  NYI
   3434     |.endif
   3435     break;
   3436 
   3437   case BC_JMP:
   3438     |  // RA = base*8 (only used by trace recorder), RD = target
   3439     |  branch_RD
   3440     |  ins_next
   3441     break;
   3442 
   3443   /* -- Function headers -------------------------------------------------- */
   3444 
   3445   case BC_FUNCF:
   3446     |.if JIT
   3447     |  hotcall
   3448     |.endif
   3449   case BC_FUNCV:  /* NYI: compiled vararg functions. */
   3450     |  // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow.
   3451     break;
   3452 
   3453   case BC_JFUNCF:
   3454 #if !LJ_HASJIT
   3455     break;
   3456 #endif
   3457   case BC_IFUNCF:
   3458     |  // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
   3459     |  lwz TMP2, L->maxstack
   3460     |   lbz TMP1, -4+PC2PROTO(numparams)(PC)
   3461     |    lwz KBASE, -4+PC2PROTO(k)(PC)
   3462     |  cmplw RA, TMP2
   3463     |   slwi TMP1, TMP1, 3
   3464     |  bgt ->vm_growstack_l
   3465     |  ins_next1
   3466     |2:
   3467     |  cmplw NARGS8:RC, TMP1		// Check for missing parameters.
   3468     |  ble >3
   3469     if (op == BC_JFUNCF) {
   3470       |  NYI
   3471     } else {
   3472       |  ins_next2
   3473     }
   3474     |
   3475     |3:  // Clear missing parameters.
   3476     |  evstddx TISNIL, BASE, NARGS8:RC
   3477     |  addi NARGS8:RC, NARGS8:RC, 8
   3478     |  b <2
   3479     break;
   3480 
   3481   case BC_JFUNCV:
   3482 #if !LJ_HASJIT
   3483     break;
   3484 #endif
   3485     |  NYI  // NYI: compiled vararg functions
   3486     break;  /* NYI: compiled vararg functions. */
   3487 
   3488   case BC_IFUNCV:
   3489     |  // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
   3490     |  lwz TMP2, L->maxstack
   3491     |   add TMP1, BASE, RC
   3492     |  add TMP0, RA, RC
   3493     |   stw LFUNC:RB, 4(TMP1)		// Store copy of LFUNC.
   3494     |   addi TMP3, RC, 8+FRAME_VARG
   3495     |    lwz KBASE, -4+PC2PROTO(k)(PC)
   3496     |  cmplw TMP0, TMP2
   3497     |   stw TMP3, 0(TMP1)		// Store delta + FRAME_VARG.
   3498     |  bge ->vm_growstack_l
   3499     |  lbz TMP2, -4+PC2PROTO(numparams)(PC)
   3500     |   mr RA, BASE
   3501     |   mr RC, TMP1
   3502     |  ins_next1
   3503     |  cmpwi TMP2, 0
   3504     |   addi BASE, TMP1, 8
   3505     |  beq >3
   3506     |1:
   3507     |  cmplw RA, RC			// Less args than parameters?
   3508     |   evldd TMP0, 0(RA)
   3509     |  bge >4
   3510     |    evstdd TISNIL, 0(RA)		// Clear old fixarg slot (help the GC).
   3511     |    addi RA, RA, 8
   3512     |2:
   3513     |  addic. TMP2, TMP2, -1
   3514     |   evstdd TMP0, 8(TMP1)
   3515     |    addi TMP1, TMP1, 8
   3516     |  bne <1
   3517     |3:
   3518     |  ins_next2
   3519     |
   3520     |4:  // Clear missing parameters.
   3521     |  evmr TMP0, TISNIL
   3522     |  b <2
   3523     break;
   3524 
   3525   case BC_FUNCC:
   3526   case BC_FUNCCW:
   3527     |  // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8
   3528     if (op == BC_FUNCC) {
   3529       |  lwz TMP3, CFUNC:RB->f
   3530     } else {
   3531       |  lwz TMP3, DISPATCH_GL(wrapf)(DISPATCH)
   3532     }
   3533     |   add TMP1, RA, NARGS8:RC
   3534     |   lwz TMP2, L->maxstack
   3535     |    add RC, BASE, NARGS8:RC
   3536     |   stw BASE, L->base
   3537     |   cmplw TMP1, TMP2
   3538     |    stw RC, L->top
   3539     |     li_vmstate C
   3540     |  mtctr TMP3
   3541     if (op == BC_FUNCCW) {
   3542       |  lwz CARG2, CFUNC:RB->f
   3543     }
   3544     |  mr CARG1, L
   3545     |   bgt ->vm_growstack_c		// Need to grow stack.
   3546     |     st_vmstate
   3547     |  bctrl				// (lua_State *L [, lua_CFunction f])
   3548     |  // Returns nresults.
   3549     |  lwz TMP1, L->top
   3550     |   slwi RD, CRET1, 3
   3551     |  lwz BASE, L->base
   3552     |    li_vmstate INTERP
   3553     |  lwz PC, FRAME_PC(BASE)		// Fetch PC of caller.
   3554     |   sub RA, TMP1, RD		// RA = L->top - nresults*8
   3555     |    st_vmstate
   3556     |  b ->vm_returnc
   3557     break;
   3558 
   3559   /* ---------------------------------------------------------------------- */
   3560 
   3561   default:
   3562     fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
   3563     exit(2);
   3564     break;
   3565   }
   3566 }
   3567 
   3568 static int build_backend(BuildCtx *ctx)
   3569 {
   3570   int op;
   3571 
   3572   dasm_growpc(Dst, BC__MAX);
   3573 
   3574   build_subroutines(ctx);
   3575 
   3576   |.code_op
   3577   for (op = 0; op < BC__MAX; op++)
   3578     build_ins(ctx, (BCOp)op, op);
   3579 
   3580   return BC__MAX;
   3581 }
   3582 
   3583 /* Emit pseudo frame-info for all assembler functions. */
   3584 static void emit_asm_debug(BuildCtx *ctx)
   3585 {
   3586   int i;
   3587   switch (ctx->mode) {
   3588   case BUILD_elfasm:
   3589     fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
   3590     fprintf(ctx->fp,
   3591 	".Lframe0:\n"
   3592 	"\t.long .LECIE0-.LSCIE0\n"
   3593 	".LSCIE0:\n"
   3594 	"\t.long 0xffffffff\n"
   3595 	"\t.byte 0x1\n"
   3596 	"\t.string \"\"\n"
   3597 	"\t.uleb128 0x1\n"
   3598 	"\t.sleb128 -4\n"
   3599 	"\t.byte 65\n"
   3600 	"\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
   3601 	"\t.align 2\n"
   3602 	".LECIE0:\n\n");
   3603     fprintf(ctx->fp,
   3604 	".LSFDE0:\n"
   3605 	"\t.long .LEFDE0-.LASFDE0\n"
   3606 	".LASFDE0:\n"
   3607 	"\t.long .Lframe0\n"
   3608 	"\t.long .Lbegin\n"
   3609 	"\t.long %d\n"
   3610 	"\t.byte 0xe\n\t.uleb128 %d\n"
   3611 	"\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
   3612 	"\t.byte 0x5\n\t.uleb128 70\n\t.sleb128 37\n",
   3613 	(int)ctx->codesz, CFRAME_SIZE);
   3614     for (i = 14; i <= 31; i++)
   3615       fprintf(ctx->fp,
   3616 	"\t.byte %d\n\t.uleb128 %d\n"
   3617 	"\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n",
   3618 	0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i));
   3619     fprintf(ctx->fp,
   3620 	"\t.align 2\n"
   3621 	".LEFDE0:\n\n");
   3622     fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
   3623     fprintf(ctx->fp,
   3624 	".Lframe1:\n"
   3625 	"\t.long .LECIE1-.LSCIE1\n"
   3626 	".LSCIE1:\n"
   3627 	"\t.long 0\n"
   3628 	"\t.byte 0x1\n"
   3629 	"\t.string \"zPR\"\n"
   3630 	"\t.uleb128 0x1\n"
   3631 	"\t.sleb128 -4\n"
   3632 	"\t.byte 65\n"
   3633 	"\t.uleb128 6\n"			/* augmentation length */
   3634 	"\t.byte 0x1b\n"			/* pcrel|sdata4 */
   3635 	"\t.long lj_err_unwind_dwarf-.\n"
   3636 	"\t.byte 0x1b\n"			/* pcrel|sdata4 */
   3637 	"\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
   3638 	"\t.align 2\n"
   3639 	".LECIE1:\n\n");
   3640     fprintf(ctx->fp,
   3641 	".LSFDE1:\n"
   3642 	"\t.long .LEFDE1-.LASFDE1\n"
   3643 	".LASFDE1:\n"
   3644 	"\t.long .LASFDE1-.Lframe1\n"
   3645 	"\t.long .Lbegin-.\n"
   3646 	"\t.long %d\n"
   3647 	"\t.uleb128 0\n"			/* augmentation length */
   3648 	"\t.byte 0xe\n\t.uleb128 %d\n"
   3649 	"\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
   3650 	"\t.byte 0x5\n\t.uleb128 70\n\t.sleb128 37\n",
   3651 	(int)ctx->codesz, CFRAME_SIZE);
   3652     for (i = 14; i <= 31; i++)
   3653       fprintf(ctx->fp,
   3654 	"\t.byte %d\n\t.uleb128 %d\n"
   3655 	"\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n",
   3656 	0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i));
   3657     fprintf(ctx->fp,
   3658 	"\t.align 2\n"
   3659 	".LEFDE1:\n\n");
   3660     break;
   3661   default:
   3662     break;
   3663   }
   3664 }
   3665