~ubuntu-branches/ubuntu/wily/sysdig/wily

« back to all changes in this revision

Viewing changes to third-party/LuaJIT-2.0.2/src/vm_ppcspe.dasc

  • Committer: Package Import Robot
  • Author(s): Evgeni Golov
  • Date: 2014-05-01 14:53:09 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20140501145309-yy0hkts9nlu43omp
Tags: 0.1.81-1
* New upstream release
* Add B-D on zlib1g-dev and use it for building
* drop LuaJIT from debian/copyright, upstream does not ship the
  copy anymore
* Only require and execute dh_dkms when building arch-independent
  stuff

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
|// Low-level VM code for PowerPC/e500 CPUs.
2
 
|// Bytecode interpreter, fast functions and helper functions.
3
 
|// Copyright (C) 2005-2013 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
 
#if LJ_52
818
 
  |  mr SAVE0, CARG1
819
 
#endif
820
 
  |  add CARG2, BASE, RD
821
 
  |   stw BASE, L->base
822
 
  |  mr CARG1, L
823
 
  |   stw PC, SAVE_PC
824
 
  |  bl extern lj_meta_len              // (lua_State *L, TValue *o)
825
 
  |  // Returns NULL (retry) or TValue * (metamethod base).
826
 
#if LJ_52
827
 
  |  cmplwi CRET1, 0
828
 
  |  bne ->vmeta_binop                  // Binop call for compatibility.
829
 
  |  mr CARG1, SAVE0
830
 
  |  b ->BC_LEN_Z
831
 
#else
832
 
  |  b ->vmeta_binop                    // Binop call for compatibility.
833
 
#endif
834
 
  |
835
 
  |//-- Call metamethod ----------------------------------------------------
836
 
  |
837
 
  |->vmeta_call:                        // Resolve and call __call metamethod.
838
 
  |  // TMP2 = old base, BASE = new base, RC = nargs*8
839
 
  |  mr CARG1, L
840
 
  |   stw TMP2, L->base                 // This is the callers base!
841
 
  |  subi CARG2, BASE, 8
842
 
  |   stw PC, SAVE_PC
843
 
  |  add CARG3, BASE, RC
844
 
  |   mr SAVE0, NARGS8:RC
845
 
  |  bl extern lj_meta_call     // (lua_State *L, TValue *func, TValue *top)
846
 
  |  lwz LFUNC:RB, FRAME_FUNC(BASE)     // Guaranteed to be a function here.
847
 
  |   addi NARGS8:RC, SAVE0, 8          // Got one more argument now.
848
 
  |  ins_call
849
 
  |
850
 
  |->vmeta_callt:                       // Resolve __call for BC_CALLT.
851
 
  |  // BASE = old base, RA = new base, RC = nargs*8
852
 
  |  mr CARG1, L
853
 
  |   stw BASE, L->base
854
 
  |  subi CARG2, RA, 8
855
 
  |   stw PC, SAVE_PC
856
 
  |  add CARG3, RA, RC
857
 
  |   mr SAVE0, NARGS8:RC
858
 
  |  bl extern lj_meta_call     // (lua_State *L, TValue *func, TValue *top)
859
 
  |  lwz TMP1, FRAME_PC(BASE)
860
 
  |   addi NARGS8:RC, SAVE0, 8          // Got one more argument now.
861
 
  |   lwz LFUNC:RB, FRAME_FUNC(RA)      // Guaranteed to be a function here.
862
 
  |  b ->BC_CALLT_Z
863
 
  |
864
 
  |//-- Argument coercion for 'for' statement ------------------------------
865
 
  |
866
 
  |->vmeta_for:
867
 
  |  mr CARG1, L
868
 
  |   stw BASE, L->base
869
 
  |  mr CARG2, RA
870
 
  |   stw PC, SAVE_PC
871
 
  |  mr SAVE0, INS
872
 
  |  bl extern lj_meta_for      // (lua_State *L, TValue *base)
873
 
  |.if JIT
874
 
  |   decode_OP1 TMP0, SAVE0
875
 
  |.endif
876
 
  |  decode_RA8 RA, SAVE0
877
 
  |.if JIT
878
 
  |   cmpwi TMP0, BC_JFORI
879
 
  |.endif
880
 
  |  decode_RD8 RD, SAVE0
881
 
  |.if JIT
882
 
  |   beq =>BC_JFORI
883
 
  |.endif
884
 
  |  b =>BC_FORI
885
 
  |
886
 
  |//-----------------------------------------------------------------------
887
 
  |//-- Fast functions -----------------------------------------------------
888
 
  |//-----------------------------------------------------------------------
889
 
  |
890
 
  |.macro .ffunc, name
891
 
  |->ff_ .. name:
892
 
  |.endmacro
893
 
  |
894
 
  |.macro .ffunc_1, name
895
 
  |->ff_ .. name:
896
 
  |  cmplwi NARGS8:RC, 8
897
 
  |   evldd CARG1, 0(BASE)
898
 
  |  blt ->fff_fallback
899
 
  |.endmacro
900
 
  |
901
 
  |.macro .ffunc_2, name
902
 
  |->ff_ .. name:
903
 
  |  cmplwi NARGS8:RC, 16
904
 
  |   evldd CARG1, 0(BASE)
905
 
  |   evldd CARG2, 8(BASE)
906
 
  |  blt ->fff_fallback
907
 
  |.endmacro
908
 
  |
909
 
  |.macro .ffunc_n, name
910
 
  |  .ffunc_1 name
911
 
  |  checknum CARG1
912
 
  |  checkfail ->fff_fallback
913
 
  |.endmacro
914
 
  |
915
 
  |.macro .ffunc_nn, name
916
 
  |  .ffunc_2 name
917
 
  |  evmergehi TMP0, CARG1, CARG2
918
 
  |  checknum TMP0
919
 
  |  checkanyfail ->fff_fallback
920
 
  |.endmacro
921
 
  |
922
 
  |// Inlined GC threshold check. Caveat: uses TMP0 and TMP1.
923
 
  |.macro ffgccheck
924
 
  |  lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
925
 
  |  lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
926
 
  |  cmplw TMP0, TMP1
927
 
  |  bgel ->fff_gcstep
928
 
  |.endmacro
929
 
  |
930
 
  |//-- Base library: checks -----------------------------------------------
931
 
  |
932
 
  |.ffunc assert
933
 
  |  cmplwi NARGS8:RC, 8
934
 
  |   evldd TMP0, 0(BASE)
935
 
  |  blt ->fff_fallback
936
 
  |  evaddw TMP1, TISNIL, TISNIL        // Synthesize LJ_TFALSE.
937
 
  |  la RA, -8(BASE)
938
 
  |   evcmpltu cr1, TMP0, TMP1
939
 
  |    lwz PC, FRAME_PC(BASE)
940
 
  |  bge cr1, ->fff_fallback
941
 
  |   evstdd TMP0, 0(RA)
942
 
  |  addi RD, NARGS8:RC, 8              // Compute (nresults+1)*8.
943
 
  |   beq ->fff_res                     // Done if exactly 1 argument.
944
 
  |  li TMP1, 8
945
 
  |  subi RC, RC, 8
946
 
  |1:
947
 
  |  cmplw TMP1, RC
948
 
  |   evlddx TMP0, BASE, TMP1
949
 
  |   evstddx TMP0, RA, TMP1
950
 
  |    addi TMP1, TMP1, 8
951
 
  |  bne <1
952
 
  |  b ->fff_res
953
 
  |
954
 
  |.ffunc type
955
 
  |  cmplwi NARGS8:RC, 8
956
 
  |   lwz CARG1, 0(BASE)
957
 
  |  blt ->fff_fallback
958
 
  |    li TMP2, ~LJ_TNUMX
959
 
  |  cmplw CARG1, TISNUM
960
 
  |  not TMP1, CARG1
961
 
  |  isellt TMP1, TMP2, TMP1
962
 
  |  slwi TMP1, TMP1, 3
963
 
  |   la TMP2, CFUNC:RB->upvalue
964
 
  |  evlddx STR:CRET1, TMP2, TMP1
965
 
  |  b ->fff_restv
966
 
  |
967
 
  |//-- Base library: getters and setters ---------------------------------
968
 
  |
969
 
  |.ffunc_1 getmetatable
970
 
  |  checktab CARG1
971
 
  |   evmergehi TMP1, CARG1, CARG1
972
 
  |  checkfail >6
973
 
  |1:  // Field metatable must be at same offset for GCtab and GCudata!
974
 
  |  lwz TAB:RB, TAB:CARG1->metatable
975
 
  |2:
976
 
  |  evmr CRET1, TISNIL
977
 
  |   cmplwi TAB:RB, 0
978
 
  |  lwz STR:RC, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])(DISPATCH)
979
 
  |   beq ->fff_restv
980
 
  |  lwz TMP0, TAB:RB->hmask
981
 
  |   evmergelo CRET1, TISTAB, TAB:RB   // Use metatable as default result.
982
 
  |  lwz TMP1, STR:RC->hash
983
 
  |  lwz NODE:TMP2, TAB:RB->node
984
 
  |   evmergelo STR:RC, TISSTR, STR:RC
985
 
  |  and TMP1, TMP1, TMP0               // idx = str->hash & tab->hmask
986
 
  |  slwi TMP0, TMP1, 5
987
 
  |  slwi TMP1, TMP1, 3
988
 
  |  sub TMP1, TMP0, TMP1
989
 
  |  add NODE:TMP2, NODE:TMP2, TMP1     // node = tab->node + (idx*32-idx*8)
990
 
  |3:  // Rearranged logic, because we expect _not_ to find the key.
991
 
  |  evldd TMP0, NODE:TMP2->key
992
 
  |   evldd TMP1, NODE:TMP2->val
993
 
  |  evcmpeq TMP0, STR:RC
994
 
  |   lwz NODE:TMP2, NODE:TMP2->next
995
 
  |  checkallok >5
996
 
  |   cmplwi NODE:TMP2, 0
997
 
  |   beq ->fff_restv                   // Not found, keep default result.
998
 
  |   b <3
999
 
  |5:
1000
 
  |  checknil TMP1
1001
 
  |  checkok ->fff_restv                // Ditto for nil value.
1002
 
  |  evmr CRET1, TMP1                   // Return value of mt.__metatable.
1003
 
  |  b ->fff_restv
1004
 
  |
1005
 
  |6:
1006
 
  |  cmpwi TMP1, LJ_TUDATA
1007
 
  |   not TMP1, TMP1
1008
 
  |  beq <1
1009
 
  |  checknum CARG1
1010
 
  |   slwi TMP1, TMP1, 2
1011
 
  |   li TMP2, 4*~LJ_TNUMX
1012
 
  |  isellt TMP1, TMP2, TMP1
1013
 
  |   la TMP2, DISPATCH_GL(gcroot[GCROOT_BASEMT])(DISPATCH)
1014
 
  |  lwzx TAB:RB, TMP2, TMP1
1015
 
  |  b <2
1016
 
  |
1017
 
  |.ffunc_2 setmetatable
1018
 
  |  // Fast path: no mt for table yet and not clearing the mt.
1019
 
  |  evmergehi TMP0, TAB:CARG1, TAB:CARG2
1020
 
  |  checktab TMP0
1021
 
  |  checkanyfail ->fff_fallback
1022
 
  |  lwz TAB:TMP1, TAB:CARG1->metatable
1023
 
  |  cmplwi TAB:TMP1, 0
1024
 
  |   lbz TMP3, TAB:CARG1->marked
1025
 
  |  bne ->fff_fallback
1026
 
  |   andi. TMP0, TMP3, LJ_GC_BLACK     // isblack(table)
1027
 
  |    stw TAB:CARG2, TAB:CARG1->metatable
1028
 
  |   beq ->fff_restv
1029
 
  |  barrierback TAB:CARG1, TMP3, TMP0
1030
 
  |  b ->fff_restv
1031
 
  |
1032
 
  |.ffunc rawget
1033
 
  |  cmplwi NARGS8:RC, 16
1034
 
  |   evldd CARG2, 0(BASE)
1035
 
  |  blt ->fff_fallback
1036
 
  |  checktab CARG2
1037
 
  |   la CARG3, 8(BASE)
1038
 
  |  checkfail ->fff_fallback
1039
 
  |   mr CARG1, L
1040
 
  |  bl extern lj_tab_get  // (lua_State *L, GCtab *t, cTValue *key)
1041
 
  |  // Returns cTValue *.
1042
 
  |  evldd CRET1, 0(CRET1)
1043
 
  |  b ->fff_restv
1044
 
  |
1045
 
  |//-- Base library: conversions ------------------------------------------
1046
 
  |
1047
 
  |.ffunc tonumber
1048
 
  |  // Only handles the number case inline (without a base argument).
1049
 
  |  cmplwi NARGS8:RC, 8
1050
 
  |   evldd CARG1, 0(BASE)
1051
 
  |  bne ->fff_fallback                 // Exactly one argument.
1052
 
  |  checknum CARG1
1053
 
  |  checkok ->fff_restv
1054
 
  |  b ->fff_fallback
1055
 
  |
1056
 
  |.ffunc_1 tostring
1057
 
  |  // Only handles the string or number case inline.
1058
 
  |  checkstr CARG1
1059
 
  |  // A __tostring method in the string base metatable is ignored.
1060
 
  |  checkok ->fff_restv                // String key?
1061
 
  |  // Handle numbers inline, unless a number base metatable is present.
1062
 
  |  lwz TMP0, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH)
1063
 
  |  checknum CARG1
1064
 
  |  cmplwi cr1, TMP0, 0
1065
 
  |   stw BASE, L->base                 // Add frame since C call can throw.
1066
 
  |  crand 4*cr0+eq, 4*cr0+lt, 4*cr1+eq
1067
 
  |   stw PC, SAVE_PC                   // Redundant (but a defined value).
1068
 
  |  bne ->fff_fallback
1069
 
  |  ffgccheck
1070
 
  |  mr CARG1, L
1071
 
  |  mr CARG2, BASE
1072
 
  |  bl extern lj_str_fromnum           // (lua_State *L, lua_Number *np)
1073
 
  |  // Returns GCstr *.
1074
 
  |  evmergelo STR:CRET1, TISSTR, STR:CRET1
1075
 
  |  b ->fff_restv
1076
 
  |
1077
 
  |//-- Base library: iterators -------------------------------------------
1078
 
  |
1079
 
  |.ffunc next
1080
 
  |  cmplwi NARGS8:RC, 8
1081
 
  |   evldd CARG2, 0(BASE)
1082
 
  |  blt ->fff_fallback
1083
 
  |   evstddx TISNIL, BASE, NARGS8:RC   // Set missing 2nd arg to nil.
1084
 
  |  checktab TAB:CARG2
1085
 
  |   lwz PC, FRAME_PC(BASE)
1086
 
  |  checkfail ->fff_fallback
1087
 
  |   stw BASE, L->base                 // Add frame since C call can throw.
1088
 
  |  mr CARG1, L
1089
 
  |   stw BASE, L->top                  // Dummy frame length is ok.
1090
 
  |  la CARG3, 8(BASE)
1091
 
  |   stw PC, SAVE_PC
1092
 
  |  bl extern lj_tab_next      // (lua_State *L, GCtab *t, TValue *key)
1093
 
  |  // Returns 0 at end of traversal.
1094
 
  |  cmplwi CRET1, 0
1095
 
  |   evmr CRET1, TISNIL
1096
 
  |  beq ->fff_restv                    // End of traversal: return nil.
1097
 
  |  evldd TMP0, 8(BASE)                // Copy key and value to results.
1098
 
  |   la RA, -8(BASE)
1099
 
  |  evldd TMP1, 16(BASE)
1100
 
  |  evstdd TMP0, 0(RA)
1101
 
  |   li RD, (2+1)*8
1102
 
  |  evstdd TMP1, 8(RA)
1103
 
  |  b ->fff_res
1104
 
  |
1105
 
  |.ffunc_1 pairs
1106
 
  |  checktab TAB:CARG1
1107
 
  |   lwz PC, FRAME_PC(BASE)
1108
 
  |  checkfail ->fff_fallback
1109
 
#if LJ_52
1110
 
  |   lwz TAB:TMP2, TAB:CARG1->metatable
1111
 
  |  evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
1112
 
  |   cmplwi TAB:TMP2, 0
1113
 
  |  la RA, -8(BASE)
1114
 
  |   bne ->fff_fallback
1115
 
#else
1116
 
  |  evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
1117
 
  |  la RA, -8(BASE)
1118
 
#endif
1119
 
  |   evstdd TISNIL, 8(BASE)
1120
 
  |  li RD, (3+1)*8
1121
 
  |  evstdd CFUNC:TMP0, 0(RA)
1122
 
  |  b ->fff_res
1123
 
  |
1124
 
  |.ffunc_2 ipairs_aux
1125
 
  |  checktab TAB:CARG1
1126
 
  |   lwz PC, FRAME_PC(BASE)
1127
 
  |  checkfail ->fff_fallback
1128
 
  |  checknum CARG2
1129
 
  |    lus TMP3, 0x3ff0
1130
 
  |  checkfail ->fff_fallback
1131
 
  |  efdctsi TMP2, CARG2
1132
 
  |   lwz TMP0, TAB:CARG1->asize
1133
 
  |    evmergelo TMP3, TMP3, ZERO
1134
 
  |   lwz TMP1, TAB:CARG1->array
1135
 
  |  efdadd CARG2, CARG2, TMP3
1136
 
  |  addi TMP2, TMP2, 1
1137
 
  |   la RA, -8(BASE)
1138
 
  |  cmplw TMP0, TMP2
1139
 
  |   slwi TMP3, TMP2, 3
1140
 
  |  evstdd CARG2, 0(RA)
1141
 
  |  ble >2                             // Not in array part?
1142
 
  |  evlddx TMP1, TMP1, TMP3
1143
 
  |1:
1144
 
  |  checknil TMP1
1145
 
  |   li RD, (0+1)*8
1146
 
  |  checkok ->fff_res                  // End of iteration, return 0 results.
1147
 
  |   li RD, (2+1)*8
1148
 
  |  evstdd TMP1, 8(RA)
1149
 
  |  b ->fff_res
1150
 
  |2:  // Check for empty hash part first. Otherwise call C function.
1151
 
  |  lwz TMP0, TAB:CARG1->hmask
1152
 
  |  cmplwi TMP0, 0
1153
 
  |   li RD, (0+1)*8
1154
 
  |  beq ->fff_res
1155
 
  |   mr CARG2, TMP2
1156
 
  |  bl extern lj_tab_getinth           // (GCtab *t, int32_t key)
1157
 
  |  // Returns cTValue * or NULL.
1158
 
  |  cmplwi CRET1, 0
1159
 
  |   li RD, (0+1)*8
1160
 
  |  beq ->fff_res
1161
 
  |  evldd TMP1, 0(CRET1)
1162
 
  |  b <1
1163
 
  |
1164
 
  |.ffunc_1 ipairs
1165
 
  |  checktab TAB:CARG1
1166
 
  |   lwz PC, FRAME_PC(BASE)
1167
 
  |  checkfail ->fff_fallback
1168
 
#if LJ_52
1169
 
  |   lwz TAB:TMP2, TAB:CARG1->metatable
1170
 
  |  evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
1171
 
  |   cmplwi TAB:TMP2, 0
1172
 
  |  la RA, -8(BASE)
1173
 
  |   bne ->fff_fallback
1174
 
#else
1175
 
  |  evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
1176
 
  |  la RA, -8(BASE)
1177
 
#endif
1178
 
  |    evsplati TMP1, 0
1179
 
  |  li RD, (3+1)*8
1180
 
  |    evstdd TMP1, 8(BASE)
1181
 
  |  evstdd CFUNC:TMP0, 0(RA)
1182
 
  |  b ->fff_res
1183
 
  |
1184
 
  |//-- Base library: catch errors ----------------------------------------
1185
 
  |
1186
 
  |.ffunc pcall
1187
 
  |  cmplwi NARGS8:RC, 8
1188
 
  |   lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1189
 
  |  blt ->fff_fallback
1190
 
  |   mr TMP2, BASE
1191
 
  |   la BASE, 8(BASE)
1192
 
  |  // Remember active hook before pcall.
1193
 
  |  rlwinm TMP3, TMP3, 32-HOOK_ACTIVE_SHIFT, 31, 31
1194
 
  |   subi NARGS8:RC, NARGS8:RC, 8
1195
 
  |  addi PC, TMP3, 8+FRAME_PCALL
1196
 
  |  b ->vm_call_dispatch
1197
 
  |
1198
 
  |.ffunc_2 xpcall
1199
 
  |  lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1200
 
  |   mr TMP2, BASE
1201
 
  |  checkfunc CARG2                    // Traceback must be a function.
1202
 
  |  checkfail ->fff_fallback
1203
 
  |   la BASE, 16(BASE)
1204
 
  |  // Remember active hook before pcall.
1205
 
  |  rlwinm TMP3, TMP3, 32-HOOK_ACTIVE_SHIFT, 31, 31
1206
 
  |   evstdd CARG2, 0(TMP2)             // Swap function and traceback.
1207
 
  |  subi NARGS8:RC, NARGS8:RC, 16
1208
 
  |   evstdd CARG1, 8(TMP2)
1209
 
  |  addi PC, TMP3, 16+FRAME_PCALL
1210
 
  |  b ->vm_call_dispatch
1211
 
  |
1212
 
  |//-- Coroutine library --------------------------------------------------
1213
 
  |
1214
 
  |.macro coroutine_resume_wrap, resume
1215
 
  |.if resume
1216
 
  |.ffunc_1 coroutine_resume
1217
 
  |  evmergehi TMP0, L:CARG1, L:CARG1
1218
 
  |.else
1219
 
  |.ffunc coroutine_wrap_aux
1220
 
  |  lwz L:CARG1, CFUNC:RB->upvalue[0].gcr
1221
 
  |.endif
1222
 
  |.if resume
1223
 
  |  cmpwi TMP0, LJ_TTHREAD
1224
 
  |  bne ->fff_fallback
1225
 
  |.endif
1226
 
  |  lbz TMP0, L:CARG1->status
1227
 
  |   lwz TMP1, L:CARG1->cframe
1228
 
  |    lwz CARG2, L:CARG1->top
1229
 
  |  cmplwi cr0, TMP0, LUA_YIELD
1230
 
  |    lwz TMP2, L:CARG1->base
1231
 
  |   cmplwi cr1, TMP1, 0
1232
 
  |   lwz TMP0, L:CARG1->maxstack
1233
 
  |    cmplw cr7, CARG2, TMP2
1234
 
  |   lwz PC, FRAME_PC(BASE)
1235
 
  |  crorc 4*cr6+lt, 4*cr0+gt, 4*cr1+eq         // st>LUA_YIELD || cframe!=0
1236
 
  |   add TMP2, CARG2, NARGS8:RC
1237
 
  |  crandc 4*cr6+gt, 4*cr7+eq, 4*cr0+eq        // base==top && st!=LUA_YIELD
1238
 
  |   cmplw cr1, TMP2, TMP0
1239
 
  |  cror 4*cr6+lt, 4*cr6+lt, 4*cr6+gt
1240
 
  |   stw PC, SAVE_PC
1241
 
  |  cror 4*cr6+lt, 4*cr6+lt, 4*cr1+gt          // cond1 || cond2 || stackov
1242
 
  |   stw BASE, L->base
1243
 
  |  blt cr6, ->fff_fallback
1244
 
  |1:
1245
 
  |.if resume
1246
 
  |  addi BASE, BASE, 8                 // Keep resumed thread in stack for GC.
1247
 
  |  subi NARGS8:RC, NARGS8:RC, 8
1248
 
  |  subi TMP2, TMP2, 8
1249
 
  |.endif
1250
 
  |  stw TMP2, L:CARG1->top
1251
 
  |  li TMP1, 0
1252
 
  |  stw BASE, L->top
1253
 
  |2:  // Move args to coroutine.
1254
 
  |  cmpw TMP1, NARGS8:RC
1255
 
  |   evlddx TMP0, BASE, TMP1
1256
 
  |  beq >3
1257
 
  |   evstddx TMP0, CARG2, TMP1
1258
 
  |  addi TMP1, TMP1, 8
1259
 
  |  b <2
1260
 
  |3:
1261
 
  |  li CARG3, 0
1262
 
  |   mr L:SAVE0, L:CARG1
1263
 
  |  li CARG4, 0
1264
 
  |  bl ->vm_resume                     // (lua_State *L, TValue *base, 0, 0)
1265
 
  |  // Returns thread status.
1266
 
  |4:
1267
 
  |  lwz TMP2, L:SAVE0->base
1268
 
  |   cmplwi CRET1, LUA_YIELD
1269
 
  |  lwz TMP3, L:SAVE0->top
1270
 
  |    li_vmstate INTERP
1271
 
  |  lwz BASE, L->base
1272
 
  |    st_vmstate
1273
 
  |   bgt >8
1274
 
  |  sub RD, TMP3, TMP2
1275
 
  |   lwz TMP0, L->maxstack
1276
 
  |  cmplwi RD, 0
1277
 
  |   add TMP1, BASE, RD
1278
 
  |  beq >6                             // No results?
1279
 
  |  cmplw TMP1, TMP0
1280
 
  |   li TMP1, 0
1281
 
  |  bgt >9                             // Need to grow stack?
1282
 
  |
1283
 
  |  subi TMP3, RD, 8
1284
 
  |   stw TMP2, L:SAVE0->top            // Clear coroutine stack.
1285
 
  |5:  // Move results from coroutine.
1286
 
  |  cmplw TMP1, TMP3
1287
 
  |   evlddx TMP0, TMP2, TMP1
1288
 
  |   evstddx TMP0, BASE, TMP1
1289
 
  |    addi TMP1, TMP1, 8
1290
 
  |  bne <5
1291
 
  |6:
1292
 
  |  andi. TMP0, PC, FRAME_TYPE
1293
 
  |.if resume
1294
 
  |  li TMP1, LJ_TTRUE
1295
 
  |   la RA, -8(BASE)
1296
 
  |  stw TMP1, -8(BASE)                 // Prepend true to results.
1297
 
  |  addi RD, RD, 16
1298
 
  |.else
1299
 
  |  mr RA, BASE
1300
 
  |  addi RD, RD, 8
1301
 
  |.endif
1302
 
  |7:
1303
 
  |    stw PC, SAVE_PC
1304
 
  |   mr MULTRES, RD
1305
 
  |  beq ->BC_RET_Z
1306
 
  |  b ->vm_return
1307
 
  |
1308
 
  |8:  // Coroutine returned with error (at co->top-1).
1309
 
  |.if resume
1310
 
  |  andi. TMP0, PC, FRAME_TYPE
1311
 
  |  la TMP3, -8(TMP3)
1312
 
  |   li TMP1, LJ_TFALSE
1313
 
  |  evldd TMP0, 0(TMP3)
1314
 
  |   stw TMP3, L:SAVE0->top            // Remove error from coroutine stack.
1315
 
  |    li RD, (2+1)*8
1316
 
  |   stw TMP1, -8(BASE)                // Prepend false to results.
1317
 
  |    la RA, -8(BASE)
1318
 
  |  evstdd TMP0, 0(BASE)               // Copy error message.
1319
 
  |  b <7
1320
 
  |.else
1321
 
  |  mr CARG1, L
1322
 
  |  mr CARG2, L:SAVE0
1323
 
  |  bl extern lj_ffh_coroutine_wrap_err  // (lua_State *L, lua_State *co)
1324
 
  |.endif
1325
 
  |
1326
 
  |9:  // Handle stack expansion on return from yield.
1327
 
  |  mr CARG1, L
1328
 
  |  srwi CARG2, RD, 3
1329
 
  |  bl extern lj_state_growstack       // (lua_State *L, int n)
1330
 
  |  li CRET1, 0
1331
 
  |  b <4
1332
 
  |.endmacro
1333
 
  |
1334
 
  |  coroutine_resume_wrap 1            // coroutine.resume
1335
 
  |  coroutine_resume_wrap 0            // coroutine.wrap
1336
 
  |
1337
 
  |.ffunc coroutine_yield
1338
 
  |  lwz TMP0, L->cframe
1339
 
  |   add TMP1, BASE, NARGS8:RC
1340
 
  |   stw BASE, L->base
1341
 
  |  andi. TMP0, TMP0, CFRAME_RESUME
1342
 
  |   stw TMP1, L->top
1343
 
  |    li CRET1, LUA_YIELD
1344
 
  |  beq ->fff_fallback
1345
 
  |   stw ZERO, L->cframe
1346
 
  |    stb CRET1, L->status
1347
 
  |  b ->vm_leave_unw
1348
 
  |
1349
 
  |//-- Math library -------------------------------------------------------
1350
 
  |
1351
 
  |.ffunc_n math_abs
1352
 
  |  efdabs CRET1, CARG1
1353
 
  |  // Fallthrough.
1354
 
  |
1355
 
  |->fff_restv:
1356
 
  |  // CRET1 = TValue result.
1357
 
  |  lwz PC, FRAME_PC(BASE)
1358
 
  |   la RA, -8(BASE)
1359
 
  |  evstdd CRET1, 0(RA)
1360
 
  |->fff_res1:
1361
 
  |  // RA = results, PC = return.
1362
 
  |  li RD, (1+1)*8
1363
 
  |->fff_res:
1364
 
  |  // RA = results, RD = (nresults+1)*8, PC = return.
1365
 
  |  andi. TMP0, PC, FRAME_TYPE
1366
 
  |   mr MULTRES, RD
1367
 
  |  bne ->vm_return
1368
 
  |  lwz INS, -4(PC)
1369
 
  |  decode_RB8 RB, INS
1370
 
  |5:
1371
 
  |  cmplw RB, RD                       // More results expected?
1372
 
  |   decode_RA8 TMP0, INS
1373
 
  |  bgt >6
1374
 
  |  ins_next1
1375
 
  |  // Adjust BASE. KBASE is assumed to be set for the calling frame.
1376
 
  |   sub BASE, RA, TMP0
1377
 
  |  ins_next2
1378
 
  |
1379
 
  |6:  // Fill up results with nil.
1380
 
  |  subi TMP1, RD, 8
1381
 
  |   addi RD, RD, 8
1382
 
  |  evstddx TISNIL, RA, TMP1
1383
 
  |  b <5
1384
 
  |
1385
 
  |.macro math_extern, func
1386
 
  |  .ffunc math_ .. func
1387
 
  |  cmplwi NARGS8:RC, 8
1388
 
  |   evldd CARG2, 0(BASE)
1389
 
  |  blt ->fff_fallback
1390
 
  |  checknum CARG2
1391
 
  |   evmergehi CARG1, CARG2, CARG2
1392
 
  |  checkfail ->fff_fallback
1393
 
  |  bl extern func@plt
1394
 
  |  evmergelo CRET1, CRET1, CRET2
1395
 
  |  b ->fff_restv
1396
 
  |.endmacro
1397
 
  |
1398
 
  |.macro math_extern2, func
1399
 
  |  .ffunc math_ .. func
1400
 
  |  cmplwi NARGS8:RC, 16
1401
 
  |   evldd CARG2, 0(BASE)
1402
 
  |   evldd CARG4, 8(BASE)
1403
 
  |  blt ->fff_fallback
1404
 
  |  evmergehi CARG1, CARG4, CARG2
1405
 
  |  checknum CARG1
1406
 
  |   evmergehi CARG3, CARG4, CARG4
1407
 
  |  checkanyfail ->fff_fallback
1408
 
  |  bl extern func@plt
1409
 
  |  evmergelo CRET1, CRET1, CRET2
1410
 
  |  b ->fff_restv
1411
 
  |.endmacro
1412
 
  |
1413
 
  |.macro math_round, func
1414
 
  |  .ffunc math_ .. func
1415
 
  |  cmplwi NARGS8:RC, 8
1416
 
  |   evldd CARG2, 0(BASE)
1417
 
  |  blt ->fff_fallback
1418
 
  |  checknum CARG2
1419
 
  |   evmergehi CARG1, CARG2, CARG2
1420
 
  |  checkfail ->fff_fallback
1421
 
  |   lwz PC, FRAME_PC(BASE)
1422
 
  |  bl ->vm_..func.._hilo;
1423
 
  |  la RA, -8(BASE)
1424
 
  |  evstdd CRET2, 0(RA)
1425
 
  |  b ->fff_res1
1426
 
  |.endmacro
1427
 
  |
1428
 
  |  math_round floor
1429
 
  |  math_round ceil
1430
 
  |
1431
 
  |  math_extern sqrt
1432
 
  |
1433
 
  |.ffunc math_log
1434
 
  |  cmplwi NARGS8:RC, 8
1435
 
  |   evldd CARG2, 0(BASE)
1436
 
  |  bne ->fff_fallback                 // Need exactly 1 argument.
1437
 
  |  checknum CARG2
1438
 
  |   evmergehi CARG1, CARG2, CARG2
1439
 
  |  checkfail ->fff_fallback
1440
 
  |  bl extern log@plt
1441
 
  |  evmergelo CRET1, CRET1, CRET2
1442
 
  |  b ->fff_restv
1443
 
  |
1444
 
  |  math_extern log10
1445
 
  |  math_extern exp
1446
 
  |  math_extern sin
1447
 
  |  math_extern cos
1448
 
  |  math_extern tan
1449
 
  |  math_extern asin
1450
 
  |  math_extern acos
1451
 
  |  math_extern atan
1452
 
  |  math_extern sinh
1453
 
  |  math_extern cosh
1454
 
  |  math_extern tanh
1455
 
  |  math_extern2 pow
1456
 
  |  math_extern2 atan2
1457
 
  |  math_extern2 fmod
1458
 
  |
1459
 
  |->ff_math_deg:
1460
 
  |.ffunc_n math_rad
1461
 
  |  evldd CARG2, CFUNC:RB->upvalue[0]
1462
 
  |  efdmul CRET1, CARG1, CARG2
1463
 
  |  b ->fff_restv
1464
 
  |
1465
 
  |.ffunc math_ldexp
1466
 
  |  cmplwi NARGS8:RC, 16
1467
 
  |   evldd CARG2, 0(BASE)
1468
 
  |   evldd CARG4, 8(BASE)
1469
 
  |  blt ->fff_fallback
1470
 
  |  evmergehi CARG1, CARG4, CARG2
1471
 
  |  checknum CARG1
1472
 
  |  checkanyfail ->fff_fallback
1473
 
  |  efdctsi CARG3, CARG4
1474
 
  |  bl extern ldexp@plt
1475
 
  |  evmergelo CRET1, CRET1, CRET2
1476
 
  |  b ->fff_restv
1477
 
  |
1478
 
  |.ffunc math_frexp
1479
 
  |  cmplwi NARGS8:RC, 8
1480
 
  |   evldd CARG2, 0(BASE)
1481
 
  |  blt ->fff_fallback
1482
 
  |  checknum CARG2
1483
 
  |   evmergehi CARG1, CARG2, CARG2
1484
 
  |  checkfail ->fff_fallback
1485
 
  |  la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
1486
 
  |   lwz PC, FRAME_PC(BASE)
1487
 
  |  bl extern frexp@plt
1488
 
  |   lwz TMP1, DISPATCH_GL(tmptv)(DISPATCH)
1489
 
  |  evmergelo CRET1, CRET1, CRET2
1490
 
  |   efdcfsi CRET2, TMP1
1491
 
  |   la RA, -8(BASE)
1492
 
  |  evstdd CRET1, 0(RA)
1493
 
  |  li RD, (2+1)*8
1494
 
  |   evstdd CRET2, 8(RA)
1495
 
  |  b ->fff_res
1496
 
  |
1497
 
  |.ffunc math_modf
1498
 
  |  cmplwi NARGS8:RC, 8
1499
 
  |   evldd CARG2, 0(BASE)
1500
 
  |  blt ->fff_fallback
1501
 
  |  checknum CARG2
1502
 
  |   evmergehi CARG1, CARG2, CARG2
1503
 
  |  checkfail ->fff_fallback
1504
 
  |  la CARG3, -8(BASE)
1505
 
  |   lwz PC, FRAME_PC(BASE)
1506
 
  |  bl extern modf@plt
1507
 
  |  evmergelo CRET1, CRET1, CRET2
1508
 
  |   la RA, -8(BASE)
1509
 
  |  evstdd CRET1, 0(BASE)
1510
 
  |  li RD, (2+1)*8
1511
 
  |  b ->fff_res
1512
 
  |
1513
 
  |.macro math_minmax, name, cmpop
1514
 
  |  .ffunc_1 name
1515
 
  |  checknum CARG1
1516
 
  |   li TMP1, 8
1517
 
  |  checkfail ->fff_fallback
1518
 
  |1:
1519
 
  |  evlddx CARG2, BASE, TMP1
1520
 
  |  cmplw cr1, TMP1, NARGS8:RC
1521
 
  |   checknum CARG2
1522
 
  |  bge cr1, ->fff_restv               // Ok, since CRET1 = CARG1.
1523
 
  |   checkfail ->fff_fallback
1524
 
  |  cmpop CARG2, CARG1
1525
 
  |   addi TMP1, TMP1, 8
1526
 
  |  crmove 4*cr0+lt, 4*cr0+gt
1527
 
  |  evsel CARG1, CARG2, CARG1
1528
 
  |  b <1
1529
 
  |.endmacro
1530
 
  |
1531
 
  |  math_minmax math_min, efdtstlt
1532
 
  |  math_minmax math_max, efdtstgt
1533
 
  |
1534
 
  |//-- String library -----------------------------------------------------
1535
 
  |
1536
 
  |.ffunc_1 string_len
1537
 
  |  checkstr STR:CARG1
1538
 
  |  checkfail ->fff_fallback
1539
 
  |  lwz TMP0, STR:CARG1->len
1540
 
  |  efdcfsi CRET1, TMP0
1541
 
  |  b ->fff_restv
1542
 
  |
1543
 
  |.ffunc string_byte                   // Only handle the 1-arg case here.
1544
 
  |  cmplwi NARGS8:RC, 8
1545
 
  |   evldd STR:CARG1, 0(BASE)
1546
 
  |  bne ->fff_fallback                 // Need exactly 1 argument.
1547
 
  |  checkstr STR:CARG1
1548
 
  |   la RA, -8(BASE)
1549
 
  |  checkfail ->fff_fallback
1550
 
  |  lwz TMP0, STR:CARG1->len
1551
 
  |   li RD, (0+1)*8
1552
 
  |    lbz TMP1, STR:CARG1[1]           // Access is always ok (NUL at end).
1553
 
  |   li TMP2, (1+1)*8
1554
 
  |  cmplwi TMP0, 0
1555
 
  |   lwz PC, FRAME_PC(BASE)
1556
 
  |    efdcfsi CRET1, TMP1
1557
 
  |  iseleq RD, RD, TMP2
1558
 
  |    evstdd CRET1, 0(RA)
1559
 
  |  b ->fff_res
1560
 
  |
1561
 
  |.ffunc string_char                   // Only handle the 1-arg case here.
1562
 
  |  ffgccheck
1563
 
  |  cmplwi NARGS8:RC, 8
1564
 
  |   evldd CARG1, 0(BASE)
1565
 
  |  bne ->fff_fallback                 // Exactly 1 argument.
1566
 
  |  checknum CARG1
1567
 
  |   la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
1568
 
  |  checkfail ->fff_fallback
1569
 
  |  efdctsiz TMP0, CARG1
1570
 
  |   li CARG3, 1
1571
 
  |  cmplwi TMP0, 255
1572
 
  |   stb TMP0, 0(CARG2)
1573
 
  |  bgt ->fff_fallback
1574
 
  |->fff_newstr:
1575
 
  |  mr CARG1, L
1576
 
  |  stw BASE, L->base
1577
 
  |  stw PC, SAVE_PC
1578
 
  |  bl extern lj_str_new               // (lua_State *L, char *str, size_t l)
1579
 
  |  // Returns GCstr *.
1580
 
  |  lwz BASE, L->base
1581
 
  |   evmergelo STR:CRET1, TISSTR, STR:CRET1
1582
 
  |  b ->fff_restv
1583
 
  |
1584
 
  |.ffunc string_sub
1585
 
  |  ffgccheck
1586
 
  |  cmplwi NARGS8:RC, 16
1587
 
  |   evldd CARG3, 16(BASE)
1588
 
  |   evldd STR:CARG1, 0(BASE)
1589
 
  |  blt ->fff_fallback
1590
 
  |   evldd CARG2, 8(BASE)
1591
 
  |   li TMP2, -1
1592
 
  |  beq >1
1593
 
  |  checknum CARG3
1594
 
  |  checkfail ->fff_fallback
1595
 
  |  efdctsiz TMP2, CARG3
1596
 
  |1:
1597
 
  |  checknum CARG2
1598
 
  |  checkfail ->fff_fallback
1599
 
  |  checkstr STR:CARG1
1600
 
  |   efdctsiz TMP1, CARG2
1601
 
  |  checkfail ->fff_fallback
1602
 
  |   lwz TMP0, STR:CARG1->len
1603
 
  |  cmplw TMP0, TMP2                   // len < end? (unsigned compare)
1604
 
  |   add TMP3, TMP2, TMP0
1605
 
  |  blt >5
1606
 
  |2:
1607
 
  |  cmpwi TMP1, 0                      // start <= 0?
1608
 
  |   add TMP3, TMP1, TMP0
1609
 
  |  ble >7
1610
 
  |3:
1611
 
  |  sub. CARG3, TMP2, TMP1
1612
 
  |    addi CARG2, STR:CARG1, #STR-1
1613
 
  |   addi CARG3, CARG3, 1
1614
 
  |    add CARG2, CARG2, TMP1
1615
 
  |  isellt CARG3, r0, CARG3
1616
 
  |  b ->fff_newstr
1617
 
  |
1618
 
  |5:  // Negative end or overflow.
1619
 
  |  cmpw TMP0, TMP2
1620
 
  |   addi TMP3, TMP3, 1
1621
 
  |  iselgt TMP2, TMP3, TMP0            // end = end > len ? len : end+len+1
1622
 
  |  b <2
1623
 
  |
1624
 
  |7:  // Negative start or underflow.
1625
 
  |   cmpwi cr1, TMP3, 0
1626
 
  |  iseleq TMP1, r0, TMP3
1627
 
  |   isel TMP1, r0, TMP1, 4*cr1+lt
1628
 
  |  addi TMP1, TMP1, 1                 // start = 1 + (start ? start+len : 0)
1629
 
  |  b <3
1630
 
  |
1631
 
  |.ffunc string_rep                    // Only handle the 1-char case inline.
1632
 
  |  ffgccheck
1633
 
  |  cmplwi NARGS8:RC, 16
1634
 
  |   evldd CARG1, 0(BASE)
1635
 
  |   evldd CARG2, 8(BASE)
1636
 
  |  bne ->fff_fallback                 // Exactly 2 arguments.
1637
 
  |  checknum CARG2
1638
 
  |  checkfail ->fff_fallback
1639
 
  |  checkstr STR:CARG1
1640
 
  |   efdctsiz CARG3, CARG2
1641
 
  |  checkfail ->fff_fallback
1642
 
  |   lwz TMP0, STR:CARG1->len
1643
 
  |  cmpwi CARG3, 0
1644
 
  |   lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1645
 
  |  ble >2                             // Count <= 0? (or non-int)
1646
 
  |   cmplwi TMP0, 1
1647
 
  |  subi TMP2, CARG3, 1
1648
 
  |   blt >2                            // Zero length string?
1649
 
  |  cmplw cr1, TMP1, CARG3
1650
 
  |   bne ->fff_fallback                // Fallback for > 1-char strings.
1651
 
  |   lbz TMP0, STR:CARG1[1]
1652
 
  |   lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1653
 
  |  blt cr1, ->fff_fallback
1654
 
  |1:  // Fill buffer with char. Yes, this is suboptimal code (do you care?).
1655
 
  |  cmplwi TMP2, 0
1656
 
  |   stbx TMP0, CARG2, TMP2
1657
 
  |   subi TMP2, TMP2, 1
1658
 
  |  bne <1
1659
 
  |  b ->fff_newstr
1660
 
  |2:  // Return empty string.
1661
 
  |  la STR:CRET1, DISPATCH_GL(strempty)(DISPATCH)
1662
 
  |  evmergelo CRET1, TISSTR, STR:CRET1
1663
 
  |  b ->fff_restv
1664
 
  |
1665
 
  |.ffunc string_reverse
1666
 
  |  ffgccheck
1667
 
  |  cmplwi NARGS8:RC, 8
1668
 
  |   evldd CARG1, 0(BASE)
1669
 
  |  blt ->fff_fallback
1670
 
  |  checkstr STR:CARG1
1671
 
  |   lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1672
 
  |  checkfail ->fff_fallback
1673
 
  |  lwz CARG3, STR:CARG1->len
1674
 
  |   la CARG1, #STR(STR:CARG1)
1675
 
  |   lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1676
 
  |   li TMP2, 0
1677
 
  |  cmplw TMP1, CARG3
1678
 
  |   subi TMP3, CARG3, 1
1679
 
  |  blt ->fff_fallback
1680
 
  |1:  // Reverse string copy.
1681
 
  |  cmpwi TMP3, 0
1682
 
  |   lbzx TMP1, CARG1, TMP2
1683
 
  |  blt ->fff_newstr
1684
 
  |   stbx TMP1, CARG2, TMP3
1685
 
  |  subi TMP3, TMP3, 1
1686
 
  |  addi TMP2, TMP2, 1
1687
 
  |  b <1
1688
 
  |
1689
 
  |.macro ffstring_case, name, lo
1690
 
  |  .ffunc name
1691
 
  |  ffgccheck
1692
 
  |  cmplwi NARGS8:RC, 8
1693
 
  |   evldd CARG1, 0(BASE)
1694
 
  |  blt ->fff_fallback
1695
 
  |  checkstr STR:CARG1
1696
 
  |   lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1697
 
  |  checkfail ->fff_fallback
1698
 
  |  lwz CARG3, STR:CARG1->len
1699
 
  |   la CARG1, #STR(STR:CARG1)
1700
 
  |   lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1701
 
  |  cmplw TMP1, CARG3
1702
 
  |   li TMP2, 0
1703
 
  |  blt ->fff_fallback
1704
 
  |1:  // ASCII case conversion.
1705
 
  |  cmplw TMP2, CARG3
1706
 
  |   lbzx TMP1, CARG1, TMP2
1707
 
  |  bge ->fff_newstr
1708
 
  |   subi TMP0, TMP1, lo
1709
 
  |    xori TMP3, TMP1, 0x20
1710
 
  |   cmplwi TMP0, 26
1711
 
  |   isellt TMP1, TMP3, TMP1
1712
 
  |   stbx TMP1, CARG2, TMP2
1713
 
  |  addi TMP2, TMP2, 1
1714
 
  |  b <1
1715
 
  |.endmacro
1716
 
  |
1717
 
  |ffstring_case string_lower, 65
1718
 
  |ffstring_case string_upper, 97
1719
 
  |
1720
 
  |//-- Table library ------------------------------------------------------
1721
 
  |
1722
 
  |.ffunc_1 table_getn
1723
 
  |  checktab CARG1
1724
 
  |  checkfail ->fff_fallback
1725
 
  |  bl extern lj_tab_len               // (GCtab *t)
1726
 
  |  // Returns uint32_t (but less than 2^31).
1727
 
  |  efdcfsi CRET1, CRET1
1728
 
  |  b ->fff_restv
1729
 
  |
1730
 
  |//-- Bit library --------------------------------------------------------
1731
 
  |
1732
 
  |.macro .ffunc_bit, name
1733
 
  |  .ffunc_n bit_..name
1734
 
  |  efdadd CARG1, CARG1, TOBIT
1735
 
  |.endmacro
1736
 
  |
1737
 
  |.ffunc_bit tobit
1738
 
  |->fff_resbit:
1739
 
  |  efdcfsi CRET1, CARG1
1740
 
  |  b ->fff_restv
1741
 
  |
1742
 
  |.macro .ffunc_bit_op, name, ins
1743
 
  |  .ffunc_bit name
1744
 
  |   li TMP1, 8
1745
 
  |1:
1746
 
  |  evlddx CARG2, BASE, TMP1
1747
 
  |  cmplw cr1, TMP1, NARGS8:RC
1748
 
  |   checknum CARG2
1749
 
  |  bge cr1, ->fff_resbit
1750
 
  |   checkfail ->fff_fallback
1751
 
  |  efdadd CARG2, CARG2, TOBIT
1752
 
  |  ins CARG1, CARG1, CARG2
1753
 
  |   addi TMP1, TMP1, 8
1754
 
  |  b <1
1755
 
  |.endmacro
1756
 
  |
1757
 
  |.ffunc_bit_op band, and
1758
 
  |.ffunc_bit_op bor, or
1759
 
  |.ffunc_bit_op bxor, xor
1760
 
  |
1761
 
  |.ffunc_bit bswap
1762
 
  |  rotlwi TMP0, CARG1, 8
1763
 
  |  rlwimi TMP0, CARG1, 24, 0, 7
1764
 
  |  rlwimi TMP0, CARG1, 24, 16, 23
1765
 
  |  efdcfsi CRET1, TMP0
1766
 
  |  b ->fff_restv
1767
 
  |
1768
 
  |.ffunc_bit bnot
1769
 
  |  not TMP0, CARG1
1770
 
  |  efdcfsi CRET1, TMP0
1771
 
  |  b ->fff_restv
1772
 
  |
1773
 
  |.macro .ffunc_bit_sh, name, ins, shmod
1774
 
  |  .ffunc_nn bit_..name
1775
 
  |  efdadd CARG2, CARG2, TOBIT
1776
 
  |   efdadd CARG1, CARG1, TOBIT
1777
 
  |.if shmod == 1
1778
 
  |  rlwinm CARG2, CARG2, 0, 27, 31
1779
 
  |.elif shmod == 2
1780
 
  |  neg CARG2, CARG2
1781
 
  |.endif
1782
 
  |  ins TMP0, CARG1, CARG2
1783
 
  |  efdcfsi CRET1, TMP0
1784
 
  |  b ->fff_restv
1785
 
  |.endmacro
1786
 
  |
1787
 
  |.ffunc_bit_sh lshift, slw, 1
1788
 
  |.ffunc_bit_sh rshift, srw, 1
1789
 
  |.ffunc_bit_sh arshift, sraw, 1
1790
 
  |.ffunc_bit_sh rol, rotlw, 0
1791
 
  |.ffunc_bit_sh ror, rotlw, 2
1792
 
  |
1793
 
  |//-----------------------------------------------------------------------
1794
 
  |
1795
 
  |->fff_fallback:                      // Call fast function fallback handler.
1796
 
  |  // BASE = new base, RB = CFUNC, RC = nargs*8
1797
 
  |  lwz TMP3, CFUNC:RB->f
1798
 
  |    add TMP1, BASE, NARGS8:RC
1799
 
  |   lwz PC, FRAME_PC(BASE)            // Fallback may overwrite PC.
1800
 
  |    addi TMP0, TMP1, 8*LUA_MINSTACK
1801
 
  |     lwz TMP2, L->maxstack
1802
 
  |   stw PC, SAVE_PC                   // Redundant (but a defined value).
1803
 
  |  cmplw TMP0, TMP2
1804
 
  |     stw BASE, L->base
1805
 
  |    stw TMP1, L->top
1806
 
  |   mr CARG1, L
1807
 
  |  bgt >5                             // Need to grow stack.
1808
 
  |  mtctr TMP3
1809
 
  |  bctrl                              // (lua_State *L)
1810
 
  |  // Either throws an error, or recovers and returns -1, 0 or nresults+1.
1811
 
  |  lwz BASE, L->base
1812
 
  |  cmpwi CRET1, 0
1813
 
  |   slwi RD, CRET1, 3
1814
 
  |   la RA, -8(BASE)
1815
 
  |  bgt ->fff_res                      // Returned nresults+1?
1816
 
  |1:  // Returned 0 or -1: retry fast path.
1817
 
  |  lwz TMP0, L->top
1818
 
  |   lwz LFUNC:RB, FRAME_FUNC(BASE)
1819
 
  |  sub NARGS8:RC, TMP0, BASE
1820
 
  |  bne ->vm_call_tail                 // Returned -1?
1821
 
  |  ins_callt                          // Returned 0: retry fast path.
1822
 
  |
1823
 
  |// Reconstruct previous base for vmeta_call during tailcall.
1824
 
  |->vm_call_tail:
1825
 
  |  andi. TMP0, PC, FRAME_TYPE
1826
 
  |   rlwinm TMP1, PC, 0, 0, 28
1827
 
  |  bne >3
1828
 
  |  lwz INS, -4(PC)
1829
 
  |  decode_RA8 TMP1, INS
1830
 
  |  addi TMP1, TMP1, 8
1831
 
  |3:
1832
 
  |  sub TMP2, BASE, TMP1
1833
 
  |  b ->vm_call_dispatch               // Resolve again for tailcall.
1834
 
  |
1835
 
  |5:  // Grow stack for fallback handler.
1836
 
  |  li CARG2, LUA_MINSTACK
1837
 
  |  bl extern lj_state_growstack       // (lua_State *L, int n)
1838
 
  |  lwz BASE, L->base
1839
 
  |  cmpw TMP0, TMP0                    // Set 4*cr0+eq to force retry.
1840
 
  |  b <1
1841
 
  |
1842
 
  |->fff_gcstep:                        // Call GC step function.
1843
 
  |  // BASE = new base, RC = nargs*8
1844
 
  |  mflr SAVE0
1845
 
  |   stw BASE, L->base
1846
 
  |  add TMP0, BASE, NARGS8:RC
1847
 
  |   stw PC, SAVE_PC                   // Redundant (but a defined value).
1848
 
  |  stw TMP0, L->top
1849
 
  |  mr CARG1, L
1850
 
  |  bl extern lj_gc_step               // (lua_State *L)
1851
 
  |   lwz BASE, L->base
1852
 
  |  mtlr SAVE0
1853
 
  |    lwz TMP0, L->top
1854
 
  |   sub NARGS8:RC, TMP0, BASE
1855
 
  |   lwz CFUNC:RB, FRAME_FUNC(BASE)
1856
 
  |  blr
1857
 
  |
1858
 
  |//-----------------------------------------------------------------------
1859
 
  |//-- Special dispatch targets -------------------------------------------
1860
 
  |//-----------------------------------------------------------------------
1861
 
  |
1862
 
  |->vm_record:                         // Dispatch target for recording phase.
1863
 
  |.if JIT
1864
 
  |  NYI
1865
 
  |.endif
1866
 
  |
1867
 
  |->vm_rethook:                        // Dispatch target for return hooks.
1868
 
  |  lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1869
 
  |  andi. TMP0, TMP3, HOOK_ACTIVE      // Hook already active?
1870
 
  |  beq >1
1871
 
  |5:  // Re-dispatch to static ins.
1872
 
  |  addi TMP1, TMP1, GG_DISP2STATIC    // Assumes decode_OP4 TMP1, INS.
1873
 
  |  lwzx TMP0, DISPATCH, TMP1
1874
 
  |  mtctr TMP0
1875
 
  |  bctr
1876
 
  |
1877
 
  |->vm_inshook:                        // Dispatch target for instr/line hooks.
1878
 
  |  lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1879
 
  |  lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH)
1880
 
  |  andi. TMP0, TMP3, HOOK_ACTIVE      // Hook already active?
1881
 
  |   rlwinm TMP0, TMP3, 31-LUA_HOOKLINE, 31, 0
1882
 
  |  bne <5
1883
 
  |
1884
 
  |   cmpwi cr1, TMP0, 0
1885
 
  |  addic. TMP2, TMP2, -1
1886
 
  |   beq cr1, <5
1887
 
  |  stw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
1888
 
  |  beq >1
1889
 
  |   bge cr1, <5
1890
 
  |1:
1891
 
  |  mr CARG1, L
1892
 
  |   stw MULTRES, SAVE_MULTRES
1893
 
  |  mr CARG2, PC
1894
 
  |   stw BASE, L->base
1895
 
  |  // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
1896
 
  |  bl extern lj_dispatch_ins          // (lua_State *L, const BCIns *pc)
1897
 
  |3:
1898
 
  |  lwz BASE, L->base
1899
 
  |4:  // Re-dispatch to static ins.
1900
 
  |  lwz INS, -4(PC)
1901
 
  |  decode_OP4 TMP1, INS
1902
 
  |   decode_RB8 RB, INS
1903
 
  |  addi TMP1, TMP1, GG_DISP2STATIC
1904
 
  |   decode_RD8 RD, INS
1905
 
  |  lwzx TMP0, DISPATCH, TMP1
1906
 
  |   decode_RA8 RA, INS
1907
 
  |   decode_RC8 RC, INS
1908
 
  |  mtctr TMP0
1909
 
  |  bctr
1910
 
  |
1911
 
  |->cont_hook:                         // Continue from hook yield.
1912
 
  |  addi PC, PC, 4
1913
 
  |  lwz MULTRES, -20(RB)               // Restore MULTRES for *M ins.
1914
 
  |  b <4
1915
 
  |
1916
 
  |->vm_hotloop:                        // Hot loop counter underflow.
1917
 
  |.if JIT
1918
 
  |  NYI
1919
 
  |.endif
1920
 
  |
1921
 
  |->vm_callhook:                       // Dispatch target for call hooks.
1922
 
  |  mr CARG2, PC
1923
 
  |.if JIT
1924
 
  |  b >1
1925
 
  |.endif
1926
 
  |
1927
 
  |->vm_hotcall:                        // Hot call counter underflow.
1928
 
  |.if JIT
1929
 
  |  ori CARG2, PC, 1
1930
 
  |1:
1931
 
  |.endif
1932
 
  |  add TMP0, BASE, RC
1933
 
  |   stw PC, SAVE_PC
1934
 
  |  mr CARG1, L
1935
 
  |   stw BASE, L->base
1936
 
  |  sub RA, RA, BASE
1937
 
  |   stw TMP0, L->top
1938
 
  |  bl extern lj_dispatch_call         // (lua_State *L, const BCIns *pc)
1939
 
  |  // Returns ASMFunction.
1940
 
  |  lwz BASE, L->base
1941
 
  |   lwz TMP0, L->top
1942
 
  |   stw ZERO, SAVE_PC                 // Invalidate for subsequent line hook.
1943
 
  |  sub NARGS8:RC, TMP0, BASE
1944
 
  |  add RA, BASE, RA
1945
 
  |  lwz LFUNC:RB, FRAME_FUNC(BASE)
1946
 
  |  mtctr CRET1
1947
 
  |  bctr
1948
 
  |
1949
 
  |//-----------------------------------------------------------------------
1950
 
  |//-- Trace exit handler -------------------------------------------------
1951
 
  |//-----------------------------------------------------------------------
1952
 
  |
1953
 
  |->vm_exit_handler:
1954
 
  |.if JIT
1955
 
  |  NYI
1956
 
  |.endif
1957
 
  |->vm_exit_interp:
1958
 
  |.if JIT
1959
 
  |  NYI
1960
 
  |.endif
1961
 
  |
1962
 
  |//-----------------------------------------------------------------------
1963
 
  |//-- Math helper functions ----------------------------------------------
1964
 
  |//-----------------------------------------------------------------------
1965
 
  |
1966
 
  |// FP value rounding. Called by math.floor/math.ceil fast functions
1967
 
  |// and from JIT code.
1968
 
  |//
1969
 
  |// This can be inlined if the CPU has the frin/friz/frip/frim instructions.
1970
 
  |// The alternative hard-float approaches have a deep dependency chain.
1971
 
  |// The resulting latency is at least 3x-7x the double-precision FP latency
1972
 
  |// (e500v2: 6cy, e600: 5cy, Cell: 10cy) or around 20-70 cycles.
1973
 
  |//
1974
 
  |// The soft-float approach is tedious, but much faster (e500v2: ~11cy/~6cy).
1975
 
  |// However it relies on a fast way to transfer the FP value to GPRs
1976
 
  |// (e500v2: 0cy for lo-word, 1cy for hi-word).
1977
 
  |//
1978
 
  |.macro vm_round, name, mode
1979
 
  |  // Used temporaries: TMP0, TMP1, TMP2, TMP3.
1980
 
  |->name.._efd:                        // Input: CARG2, output: CRET2
1981
 
  |  evmergehi CARG1, CARG2, CARG2
1982
 
  |->name.._hilo:
1983
 
  |  // Input: CARG1 (hi), CARG2 (hi, lo), output: CRET2
1984
 
  |  rlwinm TMP2, CARG1, 12, 21, 31
1985
 
  |  addic. TMP2, TMP2, -1023           // exp = exponent(x) - 1023
1986
 
  |   li TMP1, -1
1987
 
  |  cmplwi cr1, TMP2, 51               // 0 <= exp <= 51?
1988
 
  |   subfic TMP0, TMP2, 52
1989
 
  |  bgt cr1, >1
1990
 
  |   lus TMP3, 0xfff0
1991
 
  |  slw TMP0, TMP1, TMP0               // lomask = -1 << (52-exp)
1992
 
  |   sraw TMP1, TMP3, TMP2             // himask = (int32_t)0xfff00000 >> exp
1993
 
  |.if mode == 2                // trunc(x):
1994
 
  |  evmergelo TMP0, TMP1, TMP0
1995
 
  |  evand CRET2, CARG2, TMP0           // hi &= himask, lo &= lomask
1996
 
  |.else
1997
 
  |  andc TMP2, CARG2, TMP0
1998
 
  |   andc TMP3, CARG1, TMP1
1999
 
  |  or TMP2, TMP2, TMP3                // ztest = (hi&~himask) | (lo&~lomask)
2000
 
  |   srawi TMP3, CARG1, 31             // signmask = (int32_t)hi >> 31
2001
 
  |.if mode == 0                // floor(x):
2002
 
  |  and. TMP2, TMP2, TMP3              // iszero = ((ztest & signmask) == 0)
2003
 
  |.else                        // ceil(x):
2004
 
  |  andc. TMP2, TMP2, TMP3             // iszero = ((ztest & ~signmask) == 0)
2005
 
  |.endif
2006
 
  |  and CARG2, CARG2, TMP0             // lo &= lomask
2007
 
  |  and CARG1, CARG1, TMP1             // hi &= himask
2008
 
  |   subc TMP0, CARG2, TMP0
2009
 
  |  iseleq TMP0, CARG2, TMP0           // lo = iszero ? lo : lo-lomask
2010
 
  |   sube TMP1, CARG1, TMP1
2011
 
  |  iseleq TMP1, CARG1, TMP1           // hi = iszero ? hi : hi-himask+carry
2012
 
  |  evmergelo CRET2, TMP1, TMP0
2013
 
  |.endif
2014
 
  |  blr
2015
 
  |1:
2016
 
  |  bgtlr                              // Already done if >=2^52, +-inf or nan.
2017
 
  |.if mode == 2                // trunc(x):
2018
 
  |  rlwinm TMP1, CARG1, 0, 0, 0        // hi = sign(x)
2019
 
  |  li TMP0, 0
2020
 
  |  evmergelo CRET2, TMP1, TMP0
2021
 
  |.else
2022
 
  |  rlwinm TMP2, CARG1, 0, 1, 31
2023
 
  |  srawi TMP0, CARG1, 31              // signmask = (int32_t)hi >> 31
2024
 
  |  or TMP2, TMP2, CARG2               // ztest = abs(hi) | lo
2025
 
  |   lus TMP1, 0x3ff0
2026
 
  |.if mode == 0                // floor(x):
2027
 
  |  and. TMP2, TMP2, TMP0              // iszero = ((ztest & signmask) == 0)
2028
 
  |.else                        // ceil(x):
2029
 
  |  andc. TMP2, TMP2, TMP0             // iszero = ((ztest & ~signmask) == 0)
2030
 
  |.endif
2031
 
  |   li TMP0, 0
2032
 
  |  iseleq TMP1, r0, TMP1
2033
 
  |  rlwimi CARG1, TMP1, 0, 1, 31       // hi = sign(x) | (iszero ? 0.0 : 1.0)
2034
 
  |  evmergelo CRET2, CARG1, TMP0
2035
 
  |.endif
2036
 
  |  blr
2037
 
  |.endmacro
2038
 
  |
2039
 
  |->vm_floor:
2040
 
  |  mflr CARG3
2041
 
  |  evmergelo CARG2, CARG1, CARG2
2042
 
  |  bl ->vm_floor_hilo
2043
 
  |  mtlr CARG3
2044
 
  |  evmergehi CRET1, CRET2, CRET2
2045
 
  |  blr
2046
 
  |
2047
 
  |  vm_round vm_floor, 0
2048
 
  |  vm_round vm_ceil,  1
2049
 
  |.if JIT
2050
 
  |  vm_round vm_trunc, 2
2051
 
  |.else
2052
 
  |->vm_trunc_efd:
2053
 
  |->vm_trunc_hilo:
2054
 
  |.endif
2055
 
  |
2056
 
  |//-----------------------------------------------------------------------
2057
 
  |//-- Miscellaneous functions --------------------------------------------
2058
 
  |//-----------------------------------------------------------------------
2059
 
  |
2060
 
  |//-----------------------------------------------------------------------
2061
 
  |//-- FFI helper functions -----------------------------------------------
2062
 
  |//-----------------------------------------------------------------------
2063
 
  |
2064
 
  |->vm_ffi_call:
2065
 
  |.if FFI
2066
 
  |  NYI
2067
 
  |.endif
2068
 
  |
2069
 
  |//-----------------------------------------------------------------------
2070
 
}
2071
 
 
2072
 
/* Generate the code for a single instruction. */
2073
 
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2074
 
{
2075
 
  int vk = 0;
2076
 
  |=>defop:
2077
 
 
2078
 
  switch (op) {
2079
 
 
2080
 
  /* -- Comparison ops ---------------------------------------------------- */
2081
 
 
2082
 
  /* Remember: all ops branch for a true comparison, fall through otherwise. */
2083
 
 
2084
 
  case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
2085
 
    |  // RA = src1*8, RD = src2*8, JMP with RD = target
2086
 
    |  evlddx TMP0, BASE, RA
2087
 
    |   addi PC, PC, 4
2088
 
    |  evlddx TMP1, BASE, RD
2089
 
    |   addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2090
 
    |   lwz TMP2, -4(PC)
2091
 
    |  evmergehi RB, TMP0, TMP1
2092
 
    |   decode_RD4 TMP2, TMP2
2093
 
    |  checknum RB
2094
 
    |   add TMP2, TMP2, TMP3
2095
 
    |  checkanyfail ->vmeta_comp
2096
 
    |  efdcmplt TMP0, TMP1
2097
 
    if (op == BC_ISLE || op == BC_ISGT) {
2098
 
      |  efdcmpeq cr1, TMP0, TMP1
2099
 
      |  cror 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
2100
 
    }
2101
 
    if (op == BC_ISLT || op == BC_ISLE) {
2102
 
      |  iselgt PC, TMP2, PC
2103
 
    } else {
2104
 
      |  iselgt PC, PC, TMP2
2105
 
    }
2106
 
    |  ins_next
2107
 
    break;
2108
 
 
2109
 
  case BC_ISEQV: case BC_ISNEV:
2110
 
    vk = op == BC_ISEQV;
2111
 
    |  // RA = src1*8, RD = src2*8, JMP with RD = target
2112
 
    |  evlddx CARG2, BASE, RA
2113
 
    |   addi PC, PC, 4
2114
 
    |  evlddx CARG3, BASE, RD
2115
 
    |   addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2116
 
    |   lwz TMP2, -4(PC)
2117
 
    |  evmergehi RB, CARG2, CARG3
2118
 
    |   decode_RD4 TMP2, TMP2
2119
 
    |  checknum RB
2120
 
    |   add TMP2, TMP2, TMP3
2121
 
    |  checkanyfail >5
2122
 
    |  efdcmpeq CARG2, CARG3
2123
 
    if (vk) {
2124
 
      |  iselgt PC, TMP2, PC
2125
 
    } else {
2126
 
      |  iselgt PC, PC, TMP2
2127
 
    }
2128
 
    |1:
2129
 
    |  ins_next
2130
 
    |
2131
 
    |5:  // Either or both types are not numbers.
2132
 
    |  evcmpeq CARG2, CARG3
2133
 
    |   not TMP3, RB
2134
 
    |   cmplwi cr1, TMP3, ~LJ_TISPRI            // Primitive?
2135
 
    |  crorc 4*cr7+lt, 4*cr0+so, 4*cr0+lt       // 1: Same tv or different type.
2136
 
    |   cmplwi cr6, TMP3, ~LJ_TISTABUD          // Table or userdata?
2137
 
    |  crandc 4*cr7+gt, 4*cr0+lt, 4*cr1+gt      // 2: Same type and primitive.
2138
 
    |   mr SAVE0, PC
2139
 
    if (vk) {
2140
 
      |  isel PC, TMP2, PC, 4*cr7+gt
2141
 
    } else {
2142
 
      |  isel TMP2, PC, TMP2, 4*cr7+gt
2143
 
    }
2144
 
    |  cror 4*cr7+lt, 4*cr7+lt, 4*cr7+gt        // 1 or 2.
2145
 
    if (vk) {
2146
 
      |  isel PC, TMP2, PC, 4*cr0+so
2147
 
    } else {
2148
 
      |  isel PC, PC, TMP2, 4*cr0+so
2149
 
    }
2150
 
    |  blt cr7, <1                      // Done if 1 or 2.
2151
 
    |  blt cr6, <1                      // Done if not tab/ud.
2152
 
    |
2153
 
    |  // Different tables or userdatas. Need to check __eq metamethod.
2154
 
    |  // Field metatable must be at same offset for GCtab and GCudata!
2155
 
    |  lwz TAB:TMP2, TAB:CARG2->metatable
2156
 
    |   li CARG4, 1-vk                  // ne = 0 or 1.
2157
 
    |  cmplwi TAB:TMP2, 0
2158
 
    |  beq <1                           // No metatable?
2159
 
    |  lbz TMP2, TAB:TMP2->nomm
2160
 
    |  andi. TMP2, TMP2, 1<<MM_eq
2161
 
    |  bne <1                           // Or 'no __eq' flag set?
2162
 
    |  mr PC, SAVE0                     // Restore old PC.
2163
 
    |  b ->vmeta_equal                  // Handle __eq metamethod.
2164
 
    break;
2165
 
 
2166
 
  case BC_ISEQS: case BC_ISNES:
2167
 
    vk = op == BC_ISEQS;
2168
 
    |  // RA = src*8, RD = str_const*8 (~), JMP with RD = target
2169
 
    |  evlddx TMP0, BASE, RA
2170
 
    |   srwi RD, RD, 1
2171
 
    |    lwz INS, 0(PC)
2172
 
    |   subfic RD, RD, -4
2173
 
    |    addi PC, PC, 4
2174
 
    |   lwzx STR:TMP1, KBASE, RD        // KBASE-4-str_const*4
2175
 
    |    addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2176
 
    |    decode_RD4 TMP2, INS
2177
 
    |   evmergelo STR:TMP1, TISSTR, STR:TMP1
2178
 
    |    add TMP2, TMP2, TMP3
2179
 
    |  evcmpeq TMP0, STR:TMP1
2180
 
    if (vk) {
2181
 
      |  isel PC, TMP2, PC, 4*cr0+so
2182
 
    } else {
2183
 
      |  isel PC, PC, TMP2, 4*cr0+so
2184
 
    }
2185
 
    |  ins_next
2186
 
    break;
2187
 
 
2188
 
  case BC_ISEQN: case BC_ISNEN:
2189
 
    vk = op == BC_ISEQN;
2190
 
    |  // RA = src*8, RD = num_const*8, JMP with RD = target
2191
 
    |  evlddx TMP0, BASE, RA
2192
 
    |   addi PC, PC, 4
2193
 
    |  evlddx TMP1, KBASE, RD
2194
 
    |   addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2195
 
    |   lwz INS, -4(PC)
2196
 
    |  checknum TMP0
2197
 
    |  checkfail >5
2198
 
    |  efdcmpeq TMP0, TMP1
2199
 
    |1:
2200
 
    |   decode_RD4 TMP2, INS
2201
 
    |   add TMP2, TMP2, TMP3
2202
 
    if (vk) {
2203
 
      |  iselgt PC, TMP2, PC
2204
 
      |5:
2205
 
    } else {
2206
 
      |  iselgt PC, PC, TMP2
2207
 
    }
2208
 
    |3:
2209
 
    |  ins_next
2210
 
    if (!vk) {
2211
 
      |5:
2212
 
      |  decode_RD4 TMP2, INS
2213
 
      |  add PC, TMP2, TMP3
2214
 
      |  b <3
2215
 
    }
2216
 
    break;
2217
 
 
2218
 
  case BC_ISEQP: case BC_ISNEP:
2219
 
    vk = op == BC_ISEQP;
2220
 
    |  // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target
2221
 
    |  lwzx TMP0, BASE, RA
2222
 
    |   srwi TMP1, RD, 3
2223
 
    |    lwz INS, 0(PC)
2224
 
    |    addi PC, PC, 4
2225
 
    |   not TMP1, TMP1
2226
 
    |    addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2227
 
    |  cmplw TMP0, TMP1
2228
 
    |    decode_RD4 TMP2, INS
2229
 
    |    add TMP2, TMP2, TMP3
2230
 
    if (vk) {
2231
 
      |  iseleq PC, TMP2, PC
2232
 
    } else {
2233
 
      |  iseleq PC, PC, TMP2
2234
 
    }
2235
 
    |  ins_next
2236
 
    break;
2237
 
 
2238
 
  /* -- Unary test and copy ops ------------------------------------------- */
2239
 
 
2240
 
  case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
2241
 
    |  // RA = dst*8 or unused, RD = src*8, JMP with RD = target
2242
 
    |  evlddx TMP0, BASE, RD
2243
 
    |   evaddw TMP1, TISNIL, TISNIL     // Synthesize LJ_TFALSE.
2244
 
    |   lwz INS, 0(PC)
2245
 
    |  evcmpltu TMP0, TMP1
2246
 
    |   addi PC, PC, 4
2247
 
    if (op == BC_IST || op == BC_ISF) {
2248
 
      |  addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2249
 
      |  decode_RD4 TMP2, INS
2250
 
      |  add TMP2, TMP2, TMP3
2251
 
      if (op == BC_IST) {
2252
 
        |  isellt PC, TMP2, PC
2253
 
      } else {
2254
 
        |  isellt PC, PC, TMP2
2255
 
      }
2256
 
    } else {
2257
 
      if (op == BC_ISTC) {
2258
 
        |  checkfail >1
2259
 
      } else {
2260
 
        |  checkok >1
2261
 
      }
2262
 
      |  addis PC, PC, -(BCBIAS_J*4 >> 16)
2263
 
      |  decode_RD4 TMP2, INS
2264
 
      |   evstddx TMP0, BASE, RA
2265
 
      |  add PC, PC, TMP2
2266
 
      |1:
2267
 
    }
2268
 
    |  ins_next
2269
 
    break;
2270
 
 
2271
 
  /* -- Unary ops --------------------------------------------------------- */
2272
 
 
2273
 
  case BC_MOV:
2274
 
    |  // RA = dst*8, RD = src*8
2275
 
    |  ins_next1
2276
 
    |  evlddx TMP0, BASE, RD
2277
 
    |  evstddx TMP0, BASE, RA
2278
 
    |  ins_next2
2279
 
    break;
2280
 
  case BC_NOT:
2281
 
    |  // RA = dst*8, RD = src*8
2282
 
    |  ins_next1
2283
 
    |  lwzx TMP0, BASE, RD
2284
 
    |  subfic TMP1, TMP0, LJ_TTRUE
2285
 
    |  adde TMP0, TMP0, TMP1
2286
 
    |  stwx TMP0, BASE, RA
2287
 
    |  ins_next2
2288
 
    break;
2289
 
  case BC_UNM:
2290
 
    |  // RA = dst*8, RD = src*8
2291
 
    |  evlddx TMP0, BASE, RD
2292
 
    |  checknum TMP0
2293
 
    |  checkfail ->vmeta_unm
2294
 
    |  efdneg TMP0, TMP0
2295
 
    |  ins_next1
2296
 
    |  evstddx TMP0, BASE, RA
2297
 
    |  ins_next2
2298
 
    break;
2299
 
  case BC_LEN:
2300
 
    |  // RA = dst*8, RD = src*8
2301
 
    |  evlddx CARG1, BASE, RD
2302
 
    |  checkstr CARG1
2303
 
    |  checkfail >2
2304
 
    |  lwz CRET1, STR:CARG1->len
2305
 
    |1:
2306
 
    |  ins_next1
2307
 
    |  efdcfsi TMP0, CRET1
2308
 
    |  evstddx TMP0, BASE, RA
2309
 
    |  ins_next2
2310
 
    |2:
2311
 
    |  checktab CARG1
2312
 
    |  checkfail ->vmeta_len
2313
 
#if LJ_52
2314
 
    |  lwz TAB:TMP2, TAB:CARG1->metatable
2315
 
    |  cmplwi TAB:TMP2, 0
2316
 
    |  bne >9
2317
 
    |3:
2318
 
#endif
2319
 
    |->BC_LEN_Z:
2320
 
    |  bl extern lj_tab_len             // (GCtab *t)
2321
 
    |  // Returns uint32_t (but less than 2^31).
2322
 
    |  b <1
2323
 
#if LJ_52
2324
 
    |9:
2325
 
    |  lbz TMP0, TAB:TMP2->nomm
2326
 
    |  andi. TMP0, TMP0, 1<<MM_len
2327
 
    |  bne <3                           // 'no __len' flag set: done.
2328
 
    |  b ->vmeta_len
2329
 
#endif
2330
 
    break;
2331
 
 
2332
 
  /* -- Binary ops -------------------------------------------------------- */
2333
 
 
2334
 
    |.macro ins_arithpre, t0, t1
2335
 
    |  // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8
2336
 
    ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2337
 
    ||switch (vk) {
2338
 
    ||case 0:
2339
 
    |   evlddx t0, BASE, RB
2340
 
    |    checknum t0
2341
 
    |   evlddx t1, KBASE, RC
2342
 
    |    checkfail ->vmeta_arith_vn
2343
 
    ||  break;
2344
 
    ||case 1:
2345
 
    |   evlddx t1, BASE, RB
2346
 
    |    checknum t1
2347
 
    |   evlddx t0, KBASE, RC
2348
 
    |    checkfail ->vmeta_arith_nv
2349
 
    ||  break;
2350
 
    ||default:
2351
 
    |   evlddx t0, BASE, RB
2352
 
    |   evlddx t1, BASE, RC
2353
 
    |    evmergehi TMP2, t0, t1
2354
 
    |    checknum TMP2
2355
 
    |    checkanyfail ->vmeta_arith_vv
2356
 
    ||  break;
2357
 
    ||}
2358
 
    |.endmacro
2359
 
    |
2360
 
    |.macro ins_arith, ins
2361
 
    |  ins_arithpre TMP0, TMP1
2362
 
    |  ins_next1
2363
 
    |  ins TMP0, TMP0, TMP1
2364
 
    |  evstddx TMP0, BASE, RA
2365
 
    |  ins_next2
2366
 
    |.endmacro
2367
 
 
2368
 
  case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
2369
 
    |  ins_arith efdadd
2370
 
    break;
2371
 
  case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
2372
 
    |  ins_arith efdsub
2373
 
    break;
2374
 
  case BC_MULVN: case BC_MULNV: case BC_MULVV:
2375
 
    |  ins_arith efdmul
2376
 
    break;
2377
 
  case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
2378
 
    |  ins_arith efddiv
2379
 
    break;
2380
 
  case BC_MODVN:
2381
 
    |  ins_arithpre RD, SAVE0
2382
 
    |->BC_MODVN_Z:
2383
 
    |  efddiv CARG2, RD, SAVE0
2384
 
    |  bl ->vm_floor_efd                // floor(b/c)
2385
 
    |  efdmul TMP0, CRET2, SAVE0
2386
 
    |  ins_next1
2387
 
    |  efdsub TMP0, RD, TMP0            // b - floor(b/c)*c
2388
 
    |  evstddx TMP0, BASE, RA
2389
 
    |  ins_next2
2390
 
    break;
2391
 
  case BC_MODNV: case BC_MODVV:
2392
 
    |  ins_arithpre RD, SAVE0
2393
 
    |  b ->BC_MODVN_Z                   // Avoid 3 copies. It's slow anyway.
2394
 
    break;
2395
 
  case BC_POW:
2396
 
    |  evlddx CARG2, BASE, RB
2397
 
    |  evlddx CARG4, BASE, RC
2398
 
    |  evmergehi CARG1, CARG4, CARG2
2399
 
    |  checknum CARG1
2400
 
    |   evmergehi CARG3, CARG4, CARG4
2401
 
    |  checkanyfail ->vmeta_arith_vv
2402
 
    |  bl extern pow@plt
2403
 
    |  evmergelo CRET2, CRET1, CRET2
2404
 
    |  evstddx CRET2, BASE, RA
2405
 
    |  ins_next
2406
 
    break;
2407
 
 
2408
 
  case BC_CAT:
2409
 
    |  // RA = dst*8, RB = src_start*8, RC = src_end*8
2410
 
    |  sub CARG3, RC, RB
2411
 
    |   stw BASE, L->base
2412
 
    |  add CARG2, BASE, RC
2413
 
    |  mr SAVE0, RB
2414
 
    |->BC_CAT_Z:
2415
 
    |   stw PC, SAVE_PC
2416
 
    |  mr CARG1, L
2417
 
    |  srwi CARG3, CARG3, 3
2418
 
    |  bl extern lj_meta_cat            // (lua_State *L, TValue *top, int left)
2419
 
    |  // Returns NULL (finished) or TValue * (metamethod).
2420
 
    |  cmplwi CRET1, 0
2421
 
    |   lwz BASE, L->base
2422
 
    |  bne ->vmeta_binop
2423
 
    |  evlddx TMP0, BASE, SAVE0         // Copy result from RB to RA.
2424
 
    |  evstddx TMP0, BASE, RA
2425
 
    |  ins_next
2426
 
    break;
2427
 
 
2428
 
  /* -- Constant ops ------------------------------------------------------ */
2429
 
 
2430
 
  case BC_KSTR:
2431
 
    |  // RA = dst*8, RD = str_const*8 (~)
2432
 
    |  ins_next1
2433
 
    |  srwi TMP1, RD, 1
2434
 
    |  subfic TMP1, TMP1, -4
2435
 
    |  lwzx TMP0, KBASE, TMP1           // KBASE-4-str_const*4
2436
 
    |  evmergelo TMP0, TISSTR, TMP0
2437
 
    |  evstddx TMP0, BASE, RA
2438
 
    |  ins_next2
2439
 
    break;
2440
 
  case BC_KCDATA:
2441
 
    |.if FFI
2442
 
    |  // RA = dst*8, RD = cdata_const*8 (~)
2443
 
    |  ins_next1
2444
 
    |  srwi TMP1, RD, 1
2445
 
    |  subfic TMP1, TMP1, -4
2446
 
    |  lwzx TMP0, KBASE, TMP1           // KBASE-4-cdata_const*4
2447
 
    |  li TMP2, LJ_TCDATA
2448
 
    |  evmergelo TMP0, TMP2, TMP0
2449
 
    |  evstddx TMP0, BASE, RA
2450
 
    |  ins_next2
2451
 
    |.endif
2452
 
    break;
2453
 
  case BC_KSHORT:
2454
 
    |  // RA = dst*8, RD = int16_literal*8
2455
 
    |  srwi TMP1, RD, 3
2456
 
    |  extsh TMP1, TMP1
2457
 
    |  ins_next1
2458
 
    |  efdcfsi TMP0, TMP1
2459
 
    |  evstddx TMP0, BASE, RA
2460
 
    |  ins_next2
2461
 
    break;
2462
 
  case BC_KNUM:
2463
 
    |  // RA = dst*8, RD = num_const*8
2464
 
    |  evlddx TMP0, KBASE, RD
2465
 
    |  ins_next1
2466
 
    |  evstddx TMP0, BASE, RA
2467
 
    |  ins_next2
2468
 
    break;
2469
 
  case BC_KPRI:
2470
 
    |  // RA = dst*8, RD = primitive_type*8 (~)
2471
 
    |  srwi TMP1, RD, 3
2472
 
    |  not TMP0, TMP1
2473
 
    |  ins_next1
2474
 
    |  stwx TMP0, BASE, RA
2475
 
    |  ins_next2
2476
 
    break;
2477
 
  case BC_KNIL:
2478
 
    |  // RA = base*8, RD = end*8
2479
 
    |  evstddx TISNIL, BASE, RA
2480
 
    |   addi RA, RA, 8
2481
 
    |1:
2482
 
    |  evstddx TISNIL, BASE, RA
2483
 
    |  cmpw RA, RD
2484
 
    |   addi RA, RA, 8
2485
 
    |  blt <1
2486
 
    |  ins_next_
2487
 
    break;
2488
 
 
2489
 
  /* -- Upvalue and function ops ------------------------------------------ */
2490
 
 
2491
 
  case BC_UGET:
2492
 
    |  // RA = dst*8, RD = uvnum*8
2493
 
    |  ins_next1
2494
 
    |  lwz LFUNC:RB, FRAME_FUNC(BASE)
2495
 
    |   srwi RD, RD, 1
2496
 
    |   addi RD, RD, offsetof(GCfuncL, uvptr)
2497
 
    |  lwzx UPVAL:RB, LFUNC:RB, RD
2498
 
    |  lwz TMP1, UPVAL:RB->v
2499
 
    |  evldd TMP0, 0(TMP1)
2500
 
    |  evstddx TMP0, BASE, RA
2501
 
    |  ins_next2
2502
 
    break;
2503
 
  case BC_USETV:
2504
 
    |  // RA = uvnum*8, RD = src*8
2505
 
    |  lwz LFUNC:RB, FRAME_FUNC(BASE)
2506
 
    |    srwi RA, RA, 1
2507
 
    |    addi RA, RA, offsetof(GCfuncL, uvptr)
2508
 
    |   evlddx TMP1, BASE, RD
2509
 
    |  lwzx UPVAL:RB, LFUNC:RB, RA
2510
 
    |  lbz TMP3, UPVAL:RB->marked
2511
 
    |   lwz CARG2, UPVAL:RB->v
2512
 
    |  andi. TMP3, TMP3, LJ_GC_BLACK    // isblack(uv)
2513
 
    |    lbz TMP0, UPVAL:RB->closed
2514
 
    |   evmergehi TMP2, TMP1, TMP1
2515
 
    |   evstdd TMP1, 0(CARG2)
2516
 
    |    cmplwi cr1, TMP0, 0
2517
 
    |  cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
2518
 
    |   subi TMP2, TMP2, (LJ_TISNUM+1)
2519
 
    |  bne >2                           // Upvalue is closed and black?
2520
 
    |1:
2521
 
    |  ins_next
2522
 
    |
2523
 
    |2:  // Check if new value is collectable.
2524
 
    |  cmplwi TMP2, LJ_TISGCV - (LJ_TISNUM+1)
2525
 
    |  bge <1                           // tvisgcv(v)
2526
 
    |  lbz TMP3, GCOBJ:TMP1->gch.marked
2527
 
    |  andi. TMP3, TMP3, LJ_GC_WHITES   // iswhite(v)
2528
 
    |   la CARG1, GG_DISP2G(DISPATCH)
2529
 
    |  // Crossed a write barrier. Move the barrier forward.
2530
 
    |  beq <1
2531
 
    |  bl extern lj_gc_barrieruv        // (global_State *g, TValue *tv)
2532
 
    |  b <1
2533
 
    break;
2534
 
  case BC_USETS:
2535
 
    |  // RA = uvnum*8, RD = str_const*8 (~)
2536
 
    |  lwz LFUNC:RB, FRAME_FUNC(BASE)
2537
 
    |   srwi TMP1, RD, 1
2538
 
    |    srwi RA, RA, 1
2539
 
    |   subfic TMP1, TMP1, -4
2540
 
    |    addi RA, RA, offsetof(GCfuncL, uvptr)
2541
 
    |   lwzx STR:TMP1, KBASE, TMP1      // KBASE-4-str_const*4
2542
 
    |  lwzx UPVAL:RB, LFUNC:RB, RA
2543
 
    |   evmergelo STR:TMP1, TISSTR, STR:TMP1
2544
 
    |  lbz TMP3, UPVAL:RB->marked
2545
 
    |   lwz CARG2, UPVAL:RB->v
2546
 
    |  andi. TMP3, TMP3, LJ_GC_BLACK    // isblack(uv)
2547
 
    |   lbz TMP3, STR:TMP1->marked
2548
 
    |   lbz TMP2, UPVAL:RB->closed
2549
 
    |   evstdd STR:TMP1, 0(CARG2)
2550
 
    |  bne >2
2551
 
    |1:
2552
 
    |  ins_next
2553
 
    |
2554
 
    |2:  // Check if string is white and ensure upvalue is closed.
2555
 
    |  andi. TMP3, TMP3, LJ_GC_WHITES   // iswhite(str)
2556
 
    |   cmplwi cr1, TMP2, 0
2557
 
    |  cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
2558
 
    |   la CARG1, GG_DISP2G(DISPATCH)
2559
 
    |  // Crossed a write barrier. Move the barrier forward.
2560
 
    |  beq <1
2561
 
    |  bl extern lj_gc_barrieruv        // (global_State *g, TValue *tv)
2562
 
    |  b <1
2563
 
    break;
2564
 
  case BC_USETN:
2565
 
    |  // RA = uvnum*8, RD = num_const*8
2566
 
    |  ins_next1
2567
 
    |  lwz LFUNC:RB, FRAME_FUNC(BASE)
2568
 
    |   srwi RA, RA, 1
2569
 
    |   addi RA, RA, offsetof(GCfuncL, uvptr)
2570
 
    |    evlddx TMP0, KBASE, RD
2571
 
    |  lwzx UPVAL:RB, LFUNC:RB, RA
2572
 
    |  lwz TMP1, UPVAL:RB->v
2573
 
    |  evstdd TMP0, 0(TMP1)
2574
 
    |  ins_next2
2575
 
    break;
2576
 
  case BC_USETP:
2577
 
    |  // RA = uvnum*8, RD = primitive_type*8 (~)
2578
 
    |  ins_next1
2579
 
    |  lwz LFUNC:RB, FRAME_FUNC(BASE)
2580
 
    |   srwi RA, RA, 1
2581
 
    |   addi RA, RA, offsetof(GCfuncL, uvptr)
2582
 
    |    srwi TMP0, RD, 3
2583
 
    |  lwzx UPVAL:RB, LFUNC:RB, RA
2584
 
    |    not TMP0, TMP0
2585
 
    |  lwz TMP1, UPVAL:RB->v
2586
 
    |  stw TMP0, 0(TMP1)
2587
 
    |  ins_next2
2588
 
    break;
2589
 
 
2590
 
  case BC_UCLO:
2591
 
    |  // RA = level*8, RD = target
2592
 
    |  lwz TMP1, L->openupval
2593
 
    |  branch_RD                        // Do this first since RD is not saved.
2594
 
    |   stw BASE, L->base
2595
 
    |  cmplwi TMP1, 0
2596
 
    |   mr CARG1, L
2597
 
    |  beq >1
2598
 
    |   add CARG2, BASE, RA
2599
 
    |  bl extern lj_func_closeuv        // (lua_State *L, TValue *level)
2600
 
    |  lwz BASE, L->base
2601
 
    |1:
2602
 
    |  ins_next
2603
 
    break;
2604
 
 
2605
 
  case BC_FNEW:
2606
 
    |  // RA = dst*8, RD = proto_const*8 (~) (holding function prototype)
2607
 
    |  srwi TMP1, RD, 1
2608
 
    |   stw BASE, L->base
2609
 
    |  subfic TMP1, TMP1, -4
2610
 
    |   stw PC, SAVE_PC
2611
 
    |  lwzx CARG2, KBASE, TMP1          // KBASE-4-tab_const*4
2612
 
    |   mr CARG1, L
2613
 
    |  lwz CARG3, FRAME_FUNC(BASE)
2614
 
    |  // (lua_State *L, GCproto *pt, GCfuncL *parent)
2615
 
    |  bl extern lj_func_newL_gc
2616
 
    |  // Returns GCfuncL *.
2617
 
    |  lwz BASE, L->base
2618
 
    |  evmergelo LFUNC:CRET1, TISFUNC, LFUNC:CRET1
2619
 
    |  evstddx LFUNC:CRET1, BASE, RA
2620
 
    |  ins_next
2621
 
    break;
2622
 
 
2623
 
  /* -- Table ops --------------------------------------------------------- */
2624
 
 
2625
 
  case BC_TNEW:
2626
 
  case BC_TDUP:
2627
 
    |  // RA = dst*8, RD = (hbits|asize)*8 | tab_const*8 (~)
2628
 
    |  lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
2629
 
    |   mr CARG1, L
2630
 
    |  lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
2631
 
    |   stw BASE, L->base
2632
 
    |  cmplw TMP0, TMP1
2633
 
    |   stw PC, SAVE_PC
2634
 
    |  bge >5
2635
 
    |1:
2636
 
    if (op == BC_TNEW) {
2637
 
      |  rlwinm CARG2, RD, 29, 21, 31
2638
 
      |  rlwinm CARG3, RD, 18, 27, 31
2639
 
      |  cmpwi CARG2, 0x7ff
2640
 
      |   li TMP1, 0x801
2641
 
      |  iseleq CARG2, TMP1, CARG2
2642
 
      |  bl extern lj_tab_new  // (lua_State *L, int32_t asize, uint32_t hbits)
2643
 
      |  // Returns Table *.
2644
 
    } else {
2645
 
      |  srwi TMP1, RD, 1
2646
 
      |  subfic TMP1, TMP1, -4
2647
 
      |  lwzx CARG2, KBASE, TMP1                // KBASE-4-tab_const*4
2648
 
      |  bl extern lj_tab_dup  // (lua_State *L, Table *kt)
2649
 
      |  // Returns Table *.
2650
 
    }
2651
 
    |  lwz BASE, L->base
2652
 
    |  evmergelo TAB:CRET1, TISTAB, TAB:CRET1
2653
 
    |  evstddx TAB:CRET1, BASE, RA
2654
 
    |  ins_next
2655
 
    |5:
2656
 
    |  mr SAVE0, RD
2657
 
    |  bl extern lj_gc_step_fixtop  // (lua_State *L)
2658
 
    |  mr RD, SAVE0
2659
 
    |  mr CARG1, L
2660
 
    |  b <1
2661
 
    break;
2662
 
 
2663
 
  case BC_GGET:
2664
 
    |  // RA = dst*8, RD = str_const*8 (~)
2665
 
  case BC_GSET:
2666
 
    |  // RA = src*8, RD = str_const*8 (~)
2667
 
    |  lwz LFUNC:TMP2, FRAME_FUNC(BASE)
2668
 
    |   srwi TMP1, RD, 1
2669
 
    |  lwz TAB:RB, LFUNC:TMP2->env
2670
 
    |   subfic TMP1, TMP1, -4
2671
 
    |   lwzx STR:RC, KBASE, TMP1        // KBASE-4-str_const*4
2672
 
    if (op == BC_GGET) {
2673
 
      |  b ->BC_TGETS_Z
2674
 
    } else {
2675
 
      |  b ->BC_TSETS_Z
2676
 
    }
2677
 
    break;
2678
 
 
2679
 
  case BC_TGETV:
2680
 
    |  // RA = dst*8, RB = table*8, RC = key*8
2681
 
    |  evlddx TAB:RB, BASE, RB
2682
 
    |   evlddx RC, BASE, RC
2683
 
    |  checktab TAB:RB
2684
 
    |  checkfail ->vmeta_tgetv
2685
 
    |  checknum RC
2686
 
    |  checkfail >5
2687
 
    |  // Convert number key to integer
2688
 
    |  efdctsi TMP2, RC
2689
 
    |   lwz TMP0, TAB:RB->asize
2690
 
    |  efdcfsi TMP1, TMP2
2691
 
    |   cmplw cr0, TMP0, TMP2
2692
 
    |  efdcmpeq cr1, RC, TMP1
2693
 
    |   lwz TMP1, TAB:RB->array
2694
 
    |  crand 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
2695
 
    |   slwi TMP2, TMP2, 3
2696
 
    |  ble ->vmeta_tgetv                // Integer key and in array part?
2697
 
    |  evlddx TMP1, TMP1, TMP2
2698
 
    |  checknil TMP1
2699
 
    |  checkok >2
2700
 
    |1:
2701
 
    |  evstddx TMP1, BASE, RA
2702
 
    |  ins_next
2703
 
    |
2704
 
    |2:  // Check for __index if table value is nil.
2705
 
    |  lwz TAB:TMP2, TAB:RB->metatable
2706
 
    |  cmplwi TAB:TMP2, 0
2707
 
    |  beq <1                           // No metatable: done.
2708
 
    |  lbz TMP0, TAB:TMP2->nomm
2709
 
    |  andi. TMP0, TMP0, 1<<MM_index
2710
 
    |  bne <1                           // 'no __index' flag set: done.
2711
 
    |  b ->vmeta_tgetv
2712
 
    |
2713
 
    |5:
2714
 
    |  checkstr STR:RC                  // String key?
2715
 
    |  checkok ->BC_TGETS_Z
2716
 
    |  b ->vmeta_tgetv
2717
 
    break;
2718
 
  case BC_TGETS:
2719
 
    |  // RA = dst*8, RB = table*8, RC = str_const*8 (~)
2720
 
    |  evlddx TAB:RB, BASE, RB
2721
 
    |   srwi TMP1, RC, 1
2722
 
    |  checktab TAB:RB
2723
 
    |   subfic TMP1, TMP1, -4
2724
 
    |   lwzx STR:RC, KBASE, TMP1        // KBASE-4-str_const*4
2725
 
    |  checkfail ->vmeta_tgets1
2726
 
    |->BC_TGETS_Z:
2727
 
    |  // TAB:RB = GCtab *, STR:RC = GCstr *, RA = dst*8
2728
 
    |  lwz TMP0, TAB:RB->hmask
2729
 
    |  lwz TMP1, STR:RC->hash
2730
 
    |  lwz NODE:TMP2, TAB:RB->node
2731
 
    |   evmergelo STR:RC, TISSTR, STR:RC
2732
 
    |  and TMP1, TMP1, TMP0             // idx = str->hash & tab->hmask
2733
 
    |  slwi TMP0, TMP1, 5
2734
 
    |  slwi TMP1, TMP1, 3
2735
 
    |  sub TMP1, TMP0, TMP1
2736
 
    |  add NODE:TMP2, NODE:TMP2, TMP1   // node = tab->node + (idx*32-idx*8)
2737
 
    |1:
2738
 
    |  evldd TMP0, NODE:TMP2->key
2739
 
    |   evldd TMP1, NODE:TMP2->val
2740
 
    |  evcmpeq TMP0, STR:RC
2741
 
    |  checkanyfail >4
2742
 
    |   checknil TMP1
2743
 
    |   checkok >5                      // Key found, but nil value?
2744
 
    |3:
2745
 
    |   evstddx TMP1, BASE, RA
2746
 
    |  ins_next
2747
 
    |
2748
 
    |4:  // Follow hash chain.
2749
 
    |  lwz NODE:TMP2, NODE:TMP2->next
2750
 
    |  cmplwi NODE:TMP2, 0
2751
 
    |  bne <1
2752
 
    |  // End of hash chain: key not found, nil result.
2753
 
    |   evmr TMP1, TISNIL
2754
 
    |
2755
 
    |5:  // Check for __index if table value is nil.
2756
 
    |  lwz TAB:TMP2, TAB:RB->metatable
2757
 
    |  cmplwi TAB:TMP2, 0
2758
 
    |  beq <3                           // No metatable: done.
2759
 
    |  lbz TMP0, TAB:TMP2->nomm
2760
 
    |  andi. TMP0, TMP0, 1<<MM_index
2761
 
    |  bne <3                           // 'no __index' flag set: done.
2762
 
    |  b ->vmeta_tgets
2763
 
    break;
2764
 
  case BC_TGETB:
2765
 
    |  // RA = dst*8, RB = table*8, RC = index*8
2766
 
    |  evlddx TAB:RB, BASE, RB
2767
 
    |   srwi TMP0, RC, 3
2768
 
    |  checktab TAB:RB
2769
 
    |  checkfail ->vmeta_tgetb
2770
 
    |  lwz TMP1, TAB:RB->asize
2771
 
    |   lwz TMP2, TAB:RB->array
2772
 
    |  cmplw TMP0, TMP1
2773
 
    |  bge ->vmeta_tgetb
2774
 
    |  evlddx TMP1, TMP2, RC
2775
 
    |  checknil TMP1
2776
 
    |  checkok >5
2777
 
    |1:
2778
 
    |  ins_next1
2779
 
    |  evstddx TMP1, BASE, RA
2780
 
    |  ins_next2
2781
 
    |
2782
 
    |5:  // Check for __index if table value is nil.
2783
 
    |  lwz TAB:TMP2, TAB:RB->metatable
2784
 
    |  cmplwi TAB:TMP2, 0
2785
 
    |  beq <1                           // No metatable: done.
2786
 
    |  lbz TMP2, TAB:TMP2->nomm
2787
 
    |  andi. TMP2, TMP2, 1<<MM_index
2788
 
    |  bne <1                           // 'no __index' flag set: done.
2789
 
    |  b ->vmeta_tgetb                  // Caveat: preserve TMP0!
2790
 
    break;
2791
 
 
2792
 
  case BC_TSETV:
2793
 
    |  // RA = src*8, RB = table*8, RC = key*8
2794
 
    |  evlddx TAB:RB, BASE, RB
2795
 
    |   evlddx RC, BASE, RC
2796
 
    |  checktab TAB:RB
2797
 
    |  checkfail ->vmeta_tsetv
2798
 
    |  checknum RC
2799
 
    |  checkfail >5
2800
 
    |  // Convert number key to integer
2801
 
    |  efdctsi TMP2, RC
2802
 
    |    evlddx SAVE0, BASE, RA
2803
 
    |   lwz TMP0, TAB:RB->asize
2804
 
    |  efdcfsi TMP1, TMP2
2805
 
    |   cmplw cr0, TMP0, TMP2
2806
 
    |  efdcmpeq cr1, RC, TMP1
2807
 
    |   lwz TMP1, TAB:RB->array
2808
 
    |  crand 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
2809
 
    |   slwi TMP0, TMP2, 3
2810
 
    |  ble ->vmeta_tsetv                // Integer key and in array part?
2811
 
    |   lbz TMP3, TAB:RB->marked
2812
 
    |  evlddx TMP2, TMP1, TMP0
2813
 
    |  checknil TMP2
2814
 
    |  checkok >3
2815
 
    |1:
2816
 
    |  andi. TMP2, TMP3, LJ_GC_BLACK    // isblack(table)
2817
 
    |   evstddx SAVE0, TMP1, TMP0
2818
 
    |  bne >7
2819
 
    |2:
2820
 
    |  ins_next
2821
 
    |
2822
 
    |3:  // Check for __newindex if previous value is nil.
2823
 
    |  lwz TAB:TMP2, TAB:RB->metatable
2824
 
    |  cmplwi TAB:TMP2, 0
2825
 
    |  beq <1                           // No metatable: done.
2826
 
    |  lbz TMP2, TAB:TMP2->nomm
2827
 
    |  andi. TMP2, TMP2, 1<<MM_newindex
2828
 
    |  bne <1                           // 'no __newindex' flag set: done.
2829
 
    |  b ->vmeta_tsetv
2830
 
    |
2831
 
    |5:
2832
 
    |  checkstr STR:RC                  // String key?
2833
 
    |  checkok ->BC_TSETS_Z
2834
 
    |  b ->vmeta_tsetv
2835
 
    |
2836
 
    |7:  // Possible table write barrier for the value. Skip valiswhite check.
2837
 
    |  barrierback TAB:RB, TMP3, TMP0
2838
 
    |  b <2
2839
 
    break;
2840
 
  case BC_TSETS:
2841
 
    |  // RA = src*8, RB = table*8, RC = str_const*8 (~)
2842
 
    |  evlddx TAB:RB, BASE, RB
2843
 
    |   srwi TMP1, RC, 1
2844
 
    |  checktab TAB:RB
2845
 
    |   subfic TMP1, TMP1, -4
2846
 
    |   lwzx STR:RC, KBASE, TMP1        // KBASE-4-str_const*4
2847
 
    |  checkfail ->vmeta_tsets1
2848
 
    |->BC_TSETS_Z:
2849
 
    |  // TAB:RB = GCtab *, STR:RC = GCstr *, RA = src*8
2850
 
    |  lwz TMP0, TAB:RB->hmask
2851
 
    |  lwz TMP1, STR:RC->hash
2852
 
    |  lwz NODE:TMP2, TAB:RB->node
2853
 
    |   evmergelo STR:RC, TISSTR, STR:RC
2854
 
    |    stb ZERO, TAB:RB->nomm         // Clear metamethod cache.
2855
 
    |  and TMP1, TMP1, TMP0             // idx = str->hash & tab->hmask
2856
 
    |    evlddx SAVE0, BASE, RA
2857
 
    |  slwi TMP0, TMP1, 5
2858
 
    |  slwi TMP1, TMP1, 3
2859
 
    |  sub TMP1, TMP0, TMP1
2860
 
    |    lbz TMP3, TAB:RB->marked
2861
 
    |  add NODE:TMP2, NODE:TMP2, TMP1   // node = tab->node + (idx*32-idx*8)
2862
 
    |1:
2863
 
    |  evldd TMP0, NODE:TMP2->key
2864
 
    |   evldd TMP1, NODE:TMP2->val
2865
 
    |  evcmpeq TMP0, STR:RC
2866
 
    |  checkanyfail >5
2867
 
    |   checknil TMP1
2868
 
    |   checkok >4                      // Key found, but nil value?
2869
 
    |2:
2870
 
    |  andi. TMP0, TMP3, LJ_GC_BLACK    // isblack(table)
2871
 
    |    evstdd SAVE0, NODE:TMP2->val
2872
 
    |  bne >7
2873
 
    |3:
2874
 
    |  ins_next
2875
 
    |
2876
 
    |4:  // Check for __newindex if previous value is nil.
2877
 
    |  lwz TAB:TMP1, TAB:RB->metatable
2878
 
    |  cmplwi TAB:TMP1, 0
2879
 
    |  beq <2                           // No metatable: done.
2880
 
    |  lbz TMP0, TAB:TMP1->nomm
2881
 
    |  andi. TMP0, TMP0, 1<<MM_newindex
2882
 
    |  bne <2                           // 'no __newindex' flag set: done.
2883
 
    |  b ->vmeta_tsets
2884
 
    |
2885
 
    |5:  // Follow hash chain.
2886
 
    |  lwz NODE:TMP2, NODE:TMP2->next
2887
 
    |  cmplwi NODE:TMP2, 0
2888
 
    |  bne <1
2889
 
    |  // End of hash chain: key not found, add a new one.
2890
 
    |
2891
 
    |  // But check for __newindex first.
2892
 
    |  lwz TAB:TMP1, TAB:RB->metatable
2893
 
    |   la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
2894
 
    |   stw PC, SAVE_PC
2895
 
    |   mr CARG1, L
2896
 
    |  cmplwi TAB:TMP1, 0
2897
 
    |   stw BASE, L->base
2898
 
    |  beq >6                           // No metatable: continue.
2899
 
    |  lbz TMP0, TAB:TMP1->nomm
2900
 
    |  andi. TMP0, TMP0, 1<<MM_newindex
2901
 
    |  beq ->vmeta_tsets                // 'no __newindex' flag NOT set: check.
2902
 
    |6:
2903
 
    |  mr CARG2, TAB:RB
2904
 
    |  evstdd STR:RC, 0(CARG3)
2905
 
    |  bl extern lj_tab_newkey          // (lua_State *L, GCtab *t, TValue *k)
2906
 
    |  // Returns TValue *.
2907
 
    |  lwz BASE, L->base
2908
 
    |  evstdd SAVE0, 0(CRET1)
2909
 
    |  b <3                             // No 2nd write barrier needed.
2910
 
    |
2911
 
    |7:  // Possible table write barrier for the value. Skip valiswhite check.
2912
 
    |  barrierback TAB:RB, TMP3, TMP0
2913
 
    |  b <3
2914
 
    break;
2915
 
  case BC_TSETB:
2916
 
    |  // RA = src*8, RB = table*8, RC = index*8
2917
 
    |  evlddx TAB:RB, BASE, RB
2918
 
    |   srwi TMP0, RC, 3
2919
 
    |  checktab TAB:RB
2920
 
    |  checkfail ->vmeta_tsetb
2921
 
    |  lwz TMP1, TAB:RB->asize
2922
 
    |   lwz TMP2, TAB:RB->array
2923
 
    |    lbz TMP3, TAB:RB->marked
2924
 
    |  cmplw TMP0, TMP1
2925
 
    |   evlddx SAVE0, BASE, RA
2926
 
    |  bge ->vmeta_tsetb
2927
 
    |  evlddx TMP1, TMP2, RC
2928
 
    |  checknil TMP1
2929
 
    |  checkok >5
2930
 
    |1:
2931
 
    |  andi. TMP0, TMP3, LJ_GC_BLACK    // isblack(table)
2932
 
    |   evstddx SAVE0, TMP2, RC
2933
 
    |  bne >7
2934
 
    |2:
2935
 
    |  ins_next
2936
 
    |
2937
 
    |5:  // Check for __newindex if previous value is nil.
2938
 
    |  lwz TAB:TMP1, TAB:RB->metatable
2939
 
    |  cmplwi TAB:TMP1, 0
2940
 
    |  beq <1                           // No metatable: done.
2941
 
    |  lbz TMP1, TAB:TMP1->nomm
2942
 
    |  andi. TMP1, TMP1, 1<<MM_newindex
2943
 
    |  bne <1                           // 'no __newindex' flag set: done.
2944
 
    |  b ->vmeta_tsetb                  // Caveat: preserve TMP0!
2945
 
    |
2946
 
    |7:  // Possible table write barrier for the value. Skip valiswhite check.
2947
 
    |  barrierback TAB:RB, TMP3, TMP0
2948
 
    |  b <2
2949
 
    break;
2950
 
 
2951
 
  case BC_TSETM:
2952
 
    |  // RA = base*8 (table at base-1), RD = num_const*8 (start index)
2953
 
    |  add RA, BASE, RA
2954
 
    |1:
2955
 
    |   add TMP3, KBASE, RD
2956
 
    |  lwz TAB:CARG2, -4(RA)            // Guaranteed to be a table.
2957
 
    |    addic. TMP0, MULTRES, -8
2958
 
    |   lwz TMP3, 4(TMP3)               // Integer constant is in lo-word.
2959
 
    |    srwi CARG3, TMP0, 3
2960
 
    |    beq >4                         // Nothing to copy?
2961
 
    |  add CARG3, CARG3, TMP3
2962
 
    |  lwz TMP2, TAB:CARG2->asize
2963
 
    |   slwi TMP1, TMP3, 3
2964
 
    |    lbz TMP3, TAB:CARG2->marked
2965
 
    |  cmplw CARG3, TMP2
2966
 
    |   add TMP2, RA, TMP0
2967
 
    |   lwz TMP0, TAB:CARG2->array
2968
 
    |  bgt >5
2969
 
    |   add TMP1, TMP1, TMP0
2970
 
    |    andi. TMP0, TMP3, LJ_GC_BLACK  // isblack(table)
2971
 
    |3:  // Copy result slots to table.
2972
 
    |   evldd TMP0, 0(RA)
2973
 
    |  addi RA, RA, 8
2974
 
    |  cmpw cr1, RA, TMP2
2975
 
    |   evstdd TMP0, 0(TMP1)
2976
 
    |    addi TMP1, TMP1, 8
2977
 
    |  blt cr1, <3
2978
 
    |  bne >7
2979
 
    |4:
2980
 
    |  ins_next
2981
 
    |
2982
 
    |5:  // Need to resize array part.
2983
 
    |   stw BASE, L->base
2984
 
    |  mr CARG1, L
2985
 
    |   stw PC, SAVE_PC
2986
 
    |  mr SAVE0, RD
2987
 
    |  bl extern lj_tab_reasize         // (lua_State *L, GCtab *t, int nasize)
2988
 
    |  // Must not reallocate the stack.
2989
 
    |  mr RD, SAVE0
2990
 
    |  b <1
2991
 
    |
2992
 
    |7:  // Possible table write barrier for any value. Skip valiswhite check.
2993
 
    |  barrierback TAB:CARG2, TMP3, TMP0
2994
 
    |  b <4
2995
 
    break;
2996
 
 
2997
 
  /* -- Calls and vararg handling ----------------------------------------- */
2998
 
 
2999
 
  case BC_CALLM:
3000
 
    |  // RA = base*8, (RB = (nresults+1)*8,) RC = extra_nargs*8
3001
 
    |  add NARGS8:RC, NARGS8:RC, MULTRES
3002
 
    |  // Fall through. Assumes BC_CALL follows.
3003
 
    break;
3004
 
  case BC_CALL:
3005
 
    |  // RA = base*8, (RB = (nresults+1)*8,) RC = (nargs+1)*8
3006
 
    |  evlddx LFUNC:RB, BASE, RA
3007
 
    |   mr TMP2, BASE
3008
 
    |   add BASE, BASE, RA
3009
 
    |    subi NARGS8:RC, NARGS8:RC, 8
3010
 
    |  checkfunc LFUNC:RB
3011
 
    |   addi BASE, BASE, 8
3012
 
    |  checkfail ->vmeta_call
3013
 
    |  ins_call
3014
 
    break;
3015
 
 
3016
 
  case BC_CALLMT:
3017
 
    |  // RA = base*8, (RB = 0,) RC = extra_nargs*8
3018
 
    |  add NARGS8:RC, NARGS8:RC, MULTRES
3019
 
    |  // Fall through. Assumes BC_CALLT follows.
3020
 
    break;
3021
 
  case BC_CALLT:
3022
 
    |  // RA = base*8, (RB = 0,) RC = (nargs+1)*8
3023
 
    |  evlddx LFUNC:RB, BASE, RA
3024
 
    |   add RA, BASE, RA
3025
 
    |    lwz TMP1, FRAME_PC(BASE)
3026
 
    |    subi NARGS8:RC, NARGS8:RC, 8
3027
 
    |  checkfunc LFUNC:RB
3028
 
    |   addi RA, RA, 8
3029
 
    |  checkfail ->vmeta_callt
3030
 
    |->BC_CALLT_Z:
3031
 
    |  andi. TMP0, TMP1, FRAME_TYPE     // Caveat: preserve cr0 until the crand.
3032
 
    |   lbz TMP3, LFUNC:RB->ffid
3033
 
    |    xori TMP2, TMP1, FRAME_VARG
3034
 
    |    cmplwi cr1, NARGS8:RC, 0
3035
 
    |  bne >7
3036
 
    |1:
3037
 
    |  stw LFUNC:RB, FRAME_FUNC(BASE)   // Copy function down, but keep PC.
3038
 
    |  li TMP2, 0
3039
 
    |   cmplwi cr7, TMP3, 1             // (> FF_C) Calling a fast function?
3040
 
    |    beq cr1, >3
3041
 
    |2:
3042
 
    |  addi TMP3, TMP2, 8
3043
 
    |   evlddx TMP0, RA, TMP2
3044
 
    |  cmplw cr1, TMP3, NARGS8:RC
3045
 
    |   evstddx TMP0, BASE, TMP2
3046
 
    |  mr TMP2, TMP3
3047
 
    |  bne cr1, <2
3048
 
    |3:
3049
 
    |  crand 4*cr0+eq, 4*cr0+eq, 4*cr7+gt
3050
 
    |  beq >5
3051
 
    |4:
3052
 
    |  ins_callt
3053
 
    |
3054
 
    |5:  // Tailcall to a fast function with a Lua frame below.
3055
 
    |  lwz INS, -4(TMP1)
3056
 
    |  decode_RA8 RA, INS
3057
 
    |  sub TMP1, BASE, RA
3058
 
    |  lwz LFUNC:TMP1, FRAME_FUNC-8(TMP1)
3059
 
    |  lwz TMP1, LFUNC:TMP1->pc
3060
 
    |  lwz KBASE, PC2PROTO(k)(TMP1)     // Need to prepare KBASE.
3061
 
    |  b <4
3062
 
    |
3063
 
    |7:  // Tailcall from a vararg function.
3064
 
    |  andi. TMP0, TMP2, FRAME_TYPEP
3065
 
    |  bne <1                           // Vararg frame below?
3066
 
    |  sub BASE, BASE, TMP2             // Relocate BASE down.
3067
 
    |  lwz TMP1, FRAME_PC(BASE)
3068
 
    |  andi. TMP0, TMP1, FRAME_TYPE
3069
 
    |  b <1
3070
 
    break;
3071
 
 
3072
 
  case BC_ITERC:
3073
 
    |  // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 ((2+1)*8))
3074
 
    |  subi RA, RA, 24                  // evldd doesn't support neg. offsets.
3075
 
    |   mr TMP2, BASE
3076
 
    |  evlddx LFUNC:RB, BASE, RA
3077
 
    |   add BASE, BASE, RA
3078
 
    |   evldd TMP0, 8(BASE)
3079
 
    |    evldd TMP1, 16(BASE)
3080
 
    |  evstdd LFUNC:RB, 24(BASE)        // Copy callable.
3081
 
    |  checkfunc LFUNC:RB
3082
 
    |   evstdd TMP0, 32(BASE)           // Copy state.
3083
 
    |     li NARGS8:RC, 16              // Iterators get 2 arguments.
3084
 
    |    evstdd TMP1, 40(BASE)          // Copy control var.
3085
 
    |     addi BASE, BASE, 32
3086
 
    |  checkfail ->vmeta_call
3087
 
    |  ins_call
3088
 
    break;
3089
 
 
3090
 
  case BC_ITERN:
3091
 
    |  // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 (2+1)*8)
3092
 
    |.if JIT
3093
 
    |  // NYI: add hotloop, record BC_ITERN.
3094
 
    |.endif
3095
 
    |  add RA, BASE, RA
3096
 
    |  lwz TAB:RB, -12(RA)
3097
 
    |  lwz RC, -4(RA)                   // Get index from control var.
3098
 
    |  lwz TMP0, TAB:RB->asize
3099
 
    |  lwz TMP1, TAB:RB->array
3100
 
    |   addi PC, PC, 4
3101
 
    |1:  // Traverse array part.
3102
 
    |  cmplw RC, TMP0
3103
 
    |   slwi TMP3, RC, 3
3104
 
    |  bge >5                           // Index points after array part?
3105
 
    |  evlddx TMP2, TMP1, TMP3
3106
 
    |  checknil TMP2
3107
 
    |     lwz INS, -4(PC)
3108
 
    |  checkok >4
3109
 
    |   efdcfsi TMP0, RC
3110
 
    |    addi RC, RC, 1
3111
 
    |     addis TMP3, PC, -(BCBIAS_J*4 >> 16)
3112
 
    |  evstdd TMP2, 8(RA)
3113
 
    |     decode_RD4 TMP1, INS
3114
 
    |    stw RC, -4(RA)                 // Update control var.
3115
 
    |     add PC, TMP1, TMP3
3116
 
    |   evstdd TMP0, 0(RA)
3117
 
    |3:
3118
 
    |  ins_next
3119
 
    |
3120
 
    |4:  // Skip holes in array part.
3121
 
    |  addi RC, RC, 1
3122
 
    |  b <1
3123
 
    |
3124
 
    |5:  // Traverse hash part.
3125
 
    |  lwz TMP1, TAB:RB->hmask
3126
 
    |  sub RC, RC, TMP0
3127
 
    |   lwz TMP2, TAB:RB->node
3128
 
    |6:
3129
 
    |  cmplw RC, TMP1                   // End of iteration? Branch to ITERL+1.
3130
 
    |   slwi TMP3, RC, 5
3131
 
    |  bgt <3
3132
 
    |   slwi RB, RC, 3
3133
 
    |   sub TMP3, TMP3, RB
3134
 
    |  evlddx RB, TMP2, TMP3
3135
 
    |   add NODE:TMP3, TMP2, TMP3
3136
 
    |  checknil RB
3137
 
    |     lwz INS, -4(PC)
3138
 
    |  checkok >7
3139
 
    |   evldd TMP3, NODE:TMP3->key
3140
 
    |     addis TMP2, PC, -(BCBIAS_J*4 >> 16)
3141
 
    |  evstdd RB, 8(RA)
3142
 
    |    add RC, RC, TMP0
3143
 
    |     decode_RD4 TMP1, INS
3144
 
    |   evstdd TMP3, 0(RA)
3145
 
    |    addi RC, RC, 1
3146
 
    |     add PC, TMP1, TMP2
3147
 
    |    stw RC, -4(RA)                 // Update control var.
3148
 
    |  b <3
3149
 
    |
3150
 
    |7:  // Skip holes in hash part.
3151
 
    |  addi RC, RC, 1
3152
 
    |  b <6
3153
 
    break;
3154
 
 
3155
 
  case BC_ISNEXT:
3156
 
    |  // RA = base*8, RD = target (points to ITERN)
3157
 
    |  add RA, BASE, RA
3158
 
    |   li TMP2, -24
3159
 
    |  evlddx CFUNC:TMP1, RA, TMP2
3160
 
    |   lwz TMP2, -16(RA)
3161
 
    |    lwz TMP3, -8(RA)
3162
 
    |  evmergehi TMP0, CFUNC:TMP1, CFUNC:TMP1
3163
 
    |   cmpwi cr0, TMP2, LJ_TTAB
3164
 
    |  cmpwi cr1, TMP0, LJ_TFUNC
3165
 
    |    cmpwi cr6, TMP3, LJ_TNIL
3166
 
    |  bne cr1, >5
3167
 
    |  lbz TMP1, CFUNC:TMP1->ffid
3168
 
    |   crand 4*cr0+eq, 4*cr0+eq, 4*cr6+eq
3169
 
    |  cmpwi cr7, TMP1, FF_next_N
3170
 
    |    srwi TMP0, RD, 1
3171
 
    |  crand 4*cr0+eq, 4*cr0+eq, 4*cr7+eq
3172
 
    |    add TMP3, PC, TMP0
3173
 
    |  bne cr0, >5
3174
 
    |  lus TMP1, 0xfffe
3175
 
    |  ori TMP1, TMP1, 0x7fff
3176
 
    |  stw ZERO, -4(RA)                 // Initialize control var.
3177
 
    |  stw TMP1, -8(RA)
3178
 
    |    addis PC, TMP3, -(BCBIAS_J*4 >> 16)
3179
 
    |1:
3180
 
    |  ins_next
3181
 
    |5:  // Despecialize bytecode if any of the checks fail.
3182
 
    |  li TMP0, BC_JMP
3183
 
    |   li TMP1, BC_ITERC
3184
 
    |  stb TMP0, -1(PC)
3185
 
    |    addis PC, TMP3, -(BCBIAS_J*4 >> 16)
3186
 
    |   stb TMP1, 3(PC)
3187
 
    |  b <1
3188
 
    break;
3189
 
 
3190
 
  case BC_VARG:
3191
 
    |  // RA = base*8, RB = (nresults+1)*8, RC = numparams*8
3192
 
    |  lwz TMP0, FRAME_PC(BASE)
3193
 
    |  add RC, BASE, RC
3194
 
    |   add RA, BASE, RA
3195
 
    |  addi RC, RC, FRAME_VARG
3196
 
    |   add TMP2, RA, RB
3197
 
    |  subi TMP3, BASE, 8               // TMP3 = vtop
3198
 
    |  sub RC, RC, TMP0                 // RC = vbase
3199
 
    |  // Note: RC may now be even _above_ BASE if nargs was < numparams.
3200
 
    |  cmplwi cr1, RB, 0
3201
 
    |   sub. TMP1, TMP3, RC
3202
 
    |  beq cr1, >5                      // Copy all varargs?
3203
 
    |   subi TMP2, TMP2, 16
3204
 
    |   ble >2                          // No vararg slots?
3205
 
    |1:  // Copy vararg slots to destination slots.
3206
 
    |  evldd TMP0, 0(RC)
3207
 
    |   addi RC, RC, 8
3208
 
    |  evstdd TMP0, 0(RA)
3209
 
    |  cmplw RA, TMP2
3210
 
    |   cmplw cr1, RC, TMP3
3211
 
    |  bge >3                           // All destination slots filled?
3212
 
    |    addi RA, RA, 8
3213
 
    |   blt cr1, <1                     // More vararg slots?
3214
 
    |2:  // Fill up remainder with nil.
3215
 
    |  evstdd TISNIL, 0(RA)
3216
 
    |  cmplw RA, TMP2
3217
 
    |   addi RA, RA, 8
3218
 
    |  blt <2
3219
 
    |3:
3220
 
    |  ins_next
3221
 
    |
3222
 
    |5:  // Copy all varargs.
3223
 
    |  lwz TMP0, L->maxstack
3224
 
    |   li MULTRES, 8                   // MULTRES = (0+1)*8
3225
 
    |  ble <3                           // No vararg slots?
3226
 
    |  add TMP2, RA, TMP1
3227
 
    |  cmplw TMP2, TMP0
3228
 
    |   addi MULTRES, TMP1, 8
3229
 
    |  bgt >7
3230
 
    |6:
3231
 
    |  evldd TMP0, 0(RC)
3232
 
    |   addi RC, RC, 8
3233
 
    |  evstdd TMP0, 0(RA)
3234
 
    |  cmplw RC, TMP3
3235
 
    |   addi RA, RA, 8
3236
 
    |  blt <6                           // More vararg slots?
3237
 
    |  b <3
3238
 
    |
3239
 
    |7:  // Grow stack for varargs.
3240
 
    |  mr CARG1, L
3241
 
    |   stw RA, L->top
3242
 
    |  sub SAVE0, RC, BASE              // Need delta, because BASE may change.
3243
 
    |   stw BASE, L->base
3244
 
    |  sub RA, RA, BASE
3245
 
    |   stw PC, SAVE_PC
3246
 
    |  srwi CARG2, TMP1, 3
3247
 
    |  bl extern lj_state_growstack     // (lua_State *L, int n)
3248
 
    |  lwz BASE, L->base
3249
 
    |  add RA, BASE, RA
3250
 
    |  add RC, BASE, SAVE0
3251
 
    |  subi TMP3, BASE, 8
3252
 
    |  b <6
3253
 
    break;
3254
 
 
3255
 
  /* -- Returns ----------------------------------------------------------- */
3256
 
 
3257
 
  case BC_RETM:
3258
 
    |  // RA = results*8, RD = extra_nresults*8
3259
 
    |  add RD, RD, MULTRES              // MULTRES >= 8, so RD >= 8.
3260
 
    |  // Fall through. Assumes BC_RET follows.
3261
 
    break;
3262
 
 
3263
 
  case BC_RET:
3264
 
    |  // RA = results*8, RD = (nresults+1)*8
3265
 
    |  lwz PC, FRAME_PC(BASE)
3266
 
    |   add RA, BASE, RA
3267
 
    |    mr MULTRES, RD
3268
 
    |1:
3269
 
    |  andi. TMP0, PC, FRAME_TYPE
3270
 
    |   xori TMP1, PC, FRAME_VARG
3271
 
    |  bne ->BC_RETV_Z
3272
 
    |
3273
 
    |->BC_RET_Z:
3274
 
    |  // BASE = base, RA = resultptr, RD = (nresults+1)*8, PC = return
3275
 
    |   lwz INS, -4(PC)
3276
 
    |  cmpwi RD, 8
3277
 
    |   subi TMP2, BASE, 8
3278
 
    |   subi RC, RD, 8
3279
 
    |   decode_RB8 RB, INS
3280
 
    |  beq >3
3281
 
    |   li TMP1, 0
3282
 
    |2:
3283
 
    |  addi TMP3, TMP1, 8
3284
 
    |   evlddx TMP0, RA, TMP1
3285
 
    |  cmpw TMP3, RC
3286
 
    |   evstddx TMP0, TMP2, TMP1
3287
 
    |  beq >3
3288
 
    |  addi TMP1, TMP3, 8
3289
 
    |   evlddx TMP0, RA, TMP3
3290
 
    |  cmpw TMP1, RC
3291
 
    |   evstddx TMP0, TMP2, TMP3
3292
 
    |  bne <2
3293
 
    |3:
3294
 
    |5:
3295
 
    |  cmplw RB, RD
3296
 
    |   decode_RA8 RA, INS
3297
 
    |  bgt >6
3298
 
    |   sub BASE, TMP2, RA
3299
 
    |  lwz LFUNC:TMP1, FRAME_FUNC(BASE)
3300
 
    |  ins_next1
3301
 
    |  lwz TMP1, LFUNC:TMP1->pc
3302
 
    |  lwz KBASE, PC2PROTO(k)(TMP1)
3303
 
    |  ins_next2
3304
 
    |
3305
 
    |6:  // Fill up results with nil.
3306
 
    |  subi TMP1, RD, 8
3307
 
    |   addi RD, RD, 8
3308
 
    |  evstddx TISNIL, TMP2, TMP1
3309
 
    |  b <5
3310
 
    |
3311
 
    |->BC_RETV_Z:  // Non-standard return case.
3312
 
    |  andi. TMP2, TMP1, FRAME_TYPEP
3313
 
    |  bne ->vm_return
3314
 
    |  // Return from vararg function: relocate BASE down.
3315
 
    |  sub BASE, BASE, TMP1
3316
 
    |  lwz PC, FRAME_PC(BASE)
3317
 
    |  b <1
3318
 
    break;
3319
 
 
3320
 
  case BC_RET0: case BC_RET1:
3321
 
    |  // RA = results*8, RD = (nresults+1)*8
3322
 
    |  lwz PC, FRAME_PC(BASE)
3323
 
    |   add RA, BASE, RA
3324
 
    |    mr MULTRES, RD
3325
 
    |  andi. TMP0, PC, FRAME_TYPE
3326
 
    |   xori TMP1, PC, FRAME_VARG
3327
 
    |  bne ->BC_RETV_Z
3328
 
    |
3329
 
    |  lwz INS, -4(PC)
3330
 
    |   subi TMP2, BASE, 8
3331
 
    |  decode_RB8 RB, INS
3332
 
    if (op == BC_RET1) {
3333
 
      |  evldd TMP0, 0(RA)
3334
 
      |  evstdd TMP0, 0(TMP2)
3335
 
    }
3336
 
    |5:
3337
 
    |  cmplw RB, RD
3338
 
    |   decode_RA8 RA, INS
3339
 
    |  bgt >6
3340
 
    |   sub BASE, TMP2, RA
3341
 
    |  lwz LFUNC:TMP1, FRAME_FUNC(BASE)
3342
 
    |  ins_next1
3343
 
    |  lwz TMP1, LFUNC:TMP1->pc
3344
 
    |  lwz KBASE, PC2PROTO(k)(TMP1)
3345
 
    |  ins_next2
3346
 
    |
3347
 
    |6:  // Fill up results with nil.
3348
 
    |  subi TMP1, RD, 8
3349
 
    |   addi RD, RD, 8
3350
 
    |  evstddx TISNIL, TMP2, TMP1
3351
 
    |  b <5
3352
 
    break;
3353
 
 
3354
 
  /* -- Loops and branches ------------------------------------------------ */
3355
 
 
3356
 
  case BC_FORL:
3357
 
    |.if JIT
3358
 
    |  hotloop
3359
 
    |.endif
3360
 
    |  // Fall through. Assumes BC_IFORL follows.
3361
 
    break;
3362
 
 
3363
 
  case BC_JFORI:
3364
 
  case BC_JFORL:
3365
 
#if !LJ_HASJIT
3366
 
    break;
3367
 
#endif
3368
 
  case BC_FORI:
3369
 
  case BC_IFORL:
3370
 
    |  // RA = base*8, RD = target (after end of loop or start of loop)
3371
 
    vk = (op == BC_IFORL || op == BC_JFORL);
3372
 
    |  add RA, BASE, RA
3373
 
    |  evldd TMP1, FORL_IDX*8(RA)
3374
 
    |  evldd TMP3, FORL_STEP*8(RA)
3375
 
    |  evldd TMP2, FORL_STOP*8(RA)
3376
 
    if (!vk) {
3377
 
      |  evcmpgtu cr0, TMP1, TISNUM
3378
 
      |  evcmpgtu cr7, TMP3, TISNUM
3379
 
      |  evcmpgtu cr1, TMP2, TISNUM
3380
 
      |  cror 4*cr0+lt, 4*cr0+lt, 4*cr7+lt
3381
 
      |  cror 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3382
 
      |  blt ->vmeta_for
3383
 
    }
3384
 
    if (vk) {
3385
 
      |  efdadd TMP1, TMP1, TMP3
3386
 
      |  evstdd TMP1, FORL_IDX*8(RA)
3387
 
    }
3388
 
    |   evcmpgts TMP3, TISNIL
3389
 
    |  evstdd TMP1, FORL_EXT*8(RA)
3390
 
    |   bge >2
3391
 
    |  efdcmpgt TMP1, TMP2
3392
 
    |1:
3393
 
    if (op != BC_JFORL) {
3394
 
      |  srwi RD, RD, 1
3395
 
      |  add RD, PC, RD
3396
 
      if (op == BC_JFORI) {
3397
 
        |  addis PC, RD, -(BCBIAS_J*4 >> 16)
3398
 
      } else {
3399
 
        |  addis RD, RD, -(BCBIAS_J*4 >> 16)
3400
 
      }
3401
 
    }
3402
 
    if (op == BC_FORI) {
3403
 
      |  iselgt PC, RD, PC
3404
 
    } else if (op == BC_IFORL) {
3405
 
      |  iselgt PC, PC, RD
3406
 
    } else {
3407
 
      |  ble =>BC_JLOOP
3408
 
    }
3409
 
    |  ins_next
3410
 
    |2:
3411
 
    |  efdcmpgt TMP2, TMP1
3412
 
    |  b <1
3413
 
    break;
3414
 
 
3415
 
  case BC_ITERL:
3416
 
    |.if JIT
3417
 
    |  hotloop
3418
 
    |.endif
3419
 
    |  // Fall through. Assumes BC_IITERL follows.
3420
 
    break;
3421
 
 
3422
 
  case BC_JITERL:
3423
 
#if !LJ_HASJIT
3424
 
    break;
3425
 
#endif
3426
 
  case BC_IITERL:
3427
 
    |  // RA = base*8, RD = target
3428
 
    |  evlddx TMP1, BASE, RA
3429
 
    |   subi RA, RA, 8
3430
 
    |  checknil TMP1
3431
 
    |  checkok >1                       // Stop if iterator returned nil.
3432
 
    if (op == BC_JITERL) {
3433
 
      |  NYI
3434
 
    } else {
3435
 
      |  branch_RD                      // Otherwise save control var + branch.
3436
 
      |  evstddx TMP1, BASE, RA
3437
 
    }
3438
 
    |1:
3439
 
    |  ins_next
3440
 
    break;
3441
 
 
3442
 
  case BC_LOOP:
3443
 
    |  // RA = base*8, RD = target (loop extent)
3444
 
    |  // Note: RA/RD is only used by trace recorder to determine scope/extent
3445
 
    |  // This opcode does NOT jump, it's only purpose is to detect a hot loop.
3446
 
    |.if JIT
3447
 
    |  hotloop
3448
 
    |.endif
3449
 
    |  // Fall through. Assumes BC_ILOOP follows.
3450
 
    break;
3451
 
 
3452
 
  case BC_ILOOP:
3453
 
    |  // RA = base*8, RD = target (loop extent)
3454
 
    |  ins_next
3455
 
    break;
3456
 
 
3457
 
  case BC_JLOOP:
3458
 
    |.if JIT
3459
 
    |  NYI
3460
 
    |.endif
3461
 
    break;
3462
 
 
3463
 
  case BC_JMP:
3464
 
    |  // RA = base*8 (only used by trace recorder), RD = target
3465
 
    |  branch_RD
3466
 
    |  ins_next
3467
 
    break;
3468
 
 
3469
 
  /* -- Function headers -------------------------------------------------- */
3470
 
 
3471
 
  case BC_FUNCF:
3472
 
    |.if JIT
3473
 
    |  hotcall
3474
 
    |.endif
3475
 
  case BC_FUNCV:  /* NYI: compiled vararg functions. */
3476
 
    |  // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow.
3477
 
    break;
3478
 
 
3479
 
  case BC_JFUNCF:
3480
 
#if !LJ_HASJIT
3481
 
    break;
3482
 
#endif
3483
 
  case BC_IFUNCF:
3484
 
    |  // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
3485
 
    |  lwz TMP2, L->maxstack
3486
 
    |   lbz TMP1, -4+PC2PROTO(numparams)(PC)
3487
 
    |    lwz KBASE, -4+PC2PROTO(k)(PC)
3488
 
    |  cmplw RA, TMP2
3489
 
    |   slwi TMP1, TMP1, 3
3490
 
    |  bgt ->vm_growstack_l
3491
 
    |  ins_next1
3492
 
    |2:
3493
 
    |  cmplw NARGS8:RC, TMP1            // Check for missing parameters.
3494
 
    |  ble >3
3495
 
    if (op == BC_JFUNCF) {
3496
 
      |  NYI
3497
 
    } else {
3498
 
      |  ins_next2
3499
 
    }
3500
 
    |
3501
 
    |3:  // Clear missing parameters.
3502
 
    |  evstddx TISNIL, BASE, NARGS8:RC
3503
 
    |  addi NARGS8:RC, NARGS8:RC, 8
3504
 
    |  b <2
3505
 
    break;
3506
 
 
3507
 
  case BC_JFUNCV:
3508
 
#if !LJ_HASJIT
3509
 
    break;
3510
 
#endif
3511
 
    |  NYI  // NYI: compiled vararg functions
3512
 
    break;  /* NYI: compiled vararg functions. */
3513
 
 
3514
 
  case BC_IFUNCV:
3515
 
    |  // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
3516
 
    |  lwz TMP2, L->maxstack
3517
 
    |   add TMP1, BASE, RC
3518
 
    |  add TMP0, RA, RC
3519
 
    |   stw LFUNC:RB, 4(TMP1)           // Store copy of LFUNC.
3520
 
    |   addi TMP3, RC, 8+FRAME_VARG
3521
 
    |    lwz KBASE, -4+PC2PROTO(k)(PC)
3522
 
    |  cmplw TMP0, TMP2
3523
 
    |   stw TMP3, 0(TMP1)               // Store delta + FRAME_VARG.
3524
 
    |  bge ->vm_growstack_l
3525
 
    |  lbz TMP2, -4+PC2PROTO(numparams)(PC)
3526
 
    |   mr RA, BASE
3527
 
    |   mr RC, TMP1
3528
 
    |  ins_next1
3529
 
    |  cmpwi TMP2, 0
3530
 
    |   addi BASE, TMP1, 8
3531
 
    |  beq >3
3532
 
    |1:
3533
 
    |  cmplw RA, RC                     // Less args than parameters?
3534
 
    |   evldd TMP0, 0(RA)
3535
 
    |  bge >4
3536
 
    |    evstdd TISNIL, 0(RA)           // Clear old fixarg slot (help the GC).
3537
 
    |    addi RA, RA, 8
3538
 
    |2:
3539
 
    |  addic. TMP2, TMP2, -1
3540
 
    |   evstdd TMP0, 8(TMP1)
3541
 
    |    addi TMP1, TMP1, 8
3542
 
    |  bne <1
3543
 
    |3:
3544
 
    |  ins_next2
3545
 
    |
3546
 
    |4:  // Clear missing parameters.
3547
 
    |  evmr TMP0, TISNIL
3548
 
    |  b <2
3549
 
    break;
3550
 
 
3551
 
  case BC_FUNCC:
3552
 
  case BC_FUNCCW:
3553
 
    |  // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8
3554
 
    if (op == BC_FUNCC) {
3555
 
      |  lwz TMP3, CFUNC:RB->f
3556
 
    } else {
3557
 
      |  lwz TMP3, DISPATCH_GL(wrapf)(DISPATCH)
3558
 
    }
3559
 
    |   add TMP1, RA, NARGS8:RC
3560
 
    |   lwz TMP2, L->maxstack
3561
 
    |    add RC, BASE, NARGS8:RC
3562
 
    |   stw BASE, L->base
3563
 
    |   cmplw TMP1, TMP2
3564
 
    |    stw RC, L->top
3565
 
    |     li_vmstate C
3566
 
    |  mtctr TMP3
3567
 
    if (op == BC_FUNCCW) {
3568
 
      |  lwz CARG2, CFUNC:RB->f
3569
 
    }
3570
 
    |  mr CARG1, L
3571
 
    |   bgt ->vm_growstack_c            // Need to grow stack.
3572
 
    |     st_vmstate
3573
 
    |  bctrl                            // (lua_State *L [, lua_CFunction f])
3574
 
    |  // Returns nresults.
3575
 
    |  lwz TMP1, L->top
3576
 
    |   slwi RD, CRET1, 3
3577
 
    |  lwz BASE, L->base
3578
 
    |    li_vmstate INTERP
3579
 
    |  lwz PC, FRAME_PC(BASE)           // Fetch PC of caller.
3580
 
    |   sub RA, TMP1, RD                // RA = L->top - nresults*8
3581
 
    |    st_vmstate
3582
 
    |  b ->vm_returnc
3583
 
    break;
3584
 
 
3585
 
  /* ---------------------------------------------------------------------- */
3586
 
 
3587
 
  default:
3588
 
    fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
3589
 
    exit(2);
3590
 
    break;
3591
 
  }
3592
 
}
3593
 
 
3594
 
static int build_backend(BuildCtx *ctx)
3595
 
{
3596
 
  int op;
3597
 
 
3598
 
  dasm_growpc(Dst, BC__MAX);
3599
 
 
3600
 
  build_subroutines(ctx);
3601
 
 
3602
 
  |.code_op
3603
 
  for (op = 0; op < BC__MAX; op++)
3604
 
    build_ins(ctx, (BCOp)op, op);
3605
 
 
3606
 
  return BC__MAX;
3607
 
}
3608
 
 
3609
 
/* Emit pseudo frame-info for all assembler functions. */
3610
 
static void emit_asm_debug(BuildCtx *ctx)
3611
 
{
3612
 
  int i;
3613
 
  switch (ctx->mode) {
3614
 
  case BUILD_elfasm:
3615
 
    fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
3616
 
    fprintf(ctx->fp,
3617
 
        ".Lframe0:\n"
3618
 
        "\t.long .LECIE0-.LSCIE0\n"
3619
 
        ".LSCIE0:\n"
3620
 
        "\t.long 0xffffffff\n"
3621
 
        "\t.byte 0x1\n"
3622
 
        "\t.string \"\"\n"
3623
 
        "\t.uleb128 0x1\n"
3624
 
        "\t.sleb128 -4\n"
3625
 
        "\t.byte 65\n"
3626
 
        "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
3627
 
        "\t.align 2\n"
3628
 
        ".LECIE0:\n\n");
3629
 
    fprintf(ctx->fp,
3630
 
        ".LSFDE0:\n"
3631
 
        "\t.long .LEFDE0-.LASFDE0\n"
3632
 
        ".LASFDE0:\n"
3633
 
        "\t.long .Lframe0\n"
3634
 
        "\t.long .Lbegin\n"
3635
 
        "\t.long %d\n"
3636
 
        "\t.byte 0xe\n\t.uleb128 %d\n"
3637
 
        "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
3638
 
        "\t.byte 0x5\n\t.uleb128 70\n\t.sleb128 37\n",
3639
 
        (int)ctx->codesz, CFRAME_SIZE);
3640
 
    for (i = 14; i <= 31; i++)
3641
 
      fprintf(ctx->fp,
3642
 
        "\t.byte %d\n\t.uleb128 %d\n"
3643
 
        "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n",
3644
 
        0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i));
3645
 
    fprintf(ctx->fp,
3646
 
        "\t.align 2\n"
3647
 
        ".LEFDE0:\n\n");
3648
 
    fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
3649
 
    fprintf(ctx->fp,
3650
 
        ".Lframe1:\n"
3651
 
        "\t.long .LECIE1-.LSCIE1\n"
3652
 
        ".LSCIE1:\n"
3653
 
        "\t.long 0\n"
3654
 
        "\t.byte 0x1\n"
3655
 
        "\t.string \"zPR\"\n"
3656
 
        "\t.uleb128 0x1\n"
3657
 
        "\t.sleb128 -4\n"
3658
 
        "\t.byte 65\n"
3659
 
        "\t.uleb128 6\n"                        /* augmentation length */
3660
 
        "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
3661
 
        "\t.long lj_err_unwind_dwarf-.\n"
3662
 
        "\t.byte 0x1b\n"                        /* pcrel|sdata4 */
3663
 
        "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
3664
 
        "\t.align 2\n"
3665
 
        ".LECIE1:\n\n");
3666
 
    fprintf(ctx->fp,
3667
 
        ".LSFDE1:\n"
3668
 
        "\t.long .LEFDE1-.LASFDE1\n"
3669
 
        ".LASFDE1:\n"
3670
 
        "\t.long .LASFDE1-.Lframe1\n"
3671
 
        "\t.long .Lbegin-.\n"
3672
 
        "\t.long %d\n"
3673
 
        "\t.uleb128 0\n"                        /* augmentation length */
3674
 
        "\t.byte 0xe\n\t.uleb128 %d\n"
3675
 
        "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
3676
 
        "\t.byte 0x5\n\t.uleb128 70\n\t.sleb128 37\n",
3677
 
        (int)ctx->codesz, CFRAME_SIZE);
3678
 
    for (i = 14; i <= 31; i++)
3679
 
      fprintf(ctx->fp,
3680
 
        "\t.byte %d\n\t.uleb128 %d\n"
3681
 
        "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n",
3682
 
        0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i));
3683
 
    fprintf(ctx->fp,
3684
 
        "\t.align 2\n"
3685
 
        ".LEFDE1:\n\n");
3686
 
    break;
3687
 
  default:
3688
 
    break;
3689
 
  }
3690
 
}
3691