• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nickg / nvc / 23966678904

03 Apr 2026 11:59PM UTC coverage: 92.402% (+0.02%) from 92.381%
23966678904

Pull #1384

github

web-flow
Merge f2d03bd19 into 8749025fa
Pull Request #1384: Random signal initialization plugin.

76802 of 83117 relevant lines covered (92.4%)

608291.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.3
/src/jit/jit-interp.c
1
//
2
//  Copyright (C) 2022-2024  Nick Gasson
3
//
4
//  This program is free software: you can redistribute it and/or modify
5
//  it under the terms of the GNU General Public License as published by
6
//  the Free Software Foundation, either version 3 of the License, or
7
//  (at your option) any later version.
8
//
9
//  This program is distributed in the hope that it will be useful,
10
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
//  GNU General Public License for more details.
13
//
14
//  You should have received a copy of the GNU General Public License
15
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

18
#include "util.h"
19
#include "array.h"
20
#include "common.h"
21
#include "diag.h"
22
#include "jit/jit-exits.h"
23
#include "jit/jit-ffi.h"
24
#include "jit/jit-priv.h"
25
#include "printf.h"
26
#include "rt/mspace.h"
27
#include "tree.h"
28
#include "type.h"
29

30
#include <assert.h>
31
#include <ctype.h>
32
#include <inttypes.h>
33
#include <math.h>
34
#include <stdlib.h>
35
#include <string.h>
36

37
typedef struct _jit_interp {
38
   jit_scalar_t  *args;
39
   jit_scalar_t  *regs;
40
   unsigned       nargs;
41
   unsigned       pc;
42
   jit_func_t    *func;
43
   unsigned char *frame;
44
   unsigned       flags;
45
   mspace_t      *mspace;
46
   jit_anchor_t  *anchor;
47
   tlab_t        *tlab;
48
} jit_interp_t;
49

50
#ifdef DEBUG
51
#define JIT_ASSERT(expr) do {                                      \
52
      if (unlikely(!(expr))) {                                     \
53
         interp_dump(state);                                       \
54
         fatal_trace("assertion '%s' failed", #expr);              \
55
      }                                                            \
56
   } while (0)
57
#define CANNOT_HANDLE(value) do {                                  \
58
      interp_dump(state);                                          \
59
      fatal_trace("cannot handle value kind %d", value.kind);      \
60
   } while (0)
61
#else
62
#define JIT_ASSERT(expr)
63
#define CANNOT_HANDLE(value) __builtin_unreachable()
64
#endif
65

66
#define FOR_EACH_SIZE(sz, macro) do {                   \
67
      assert((sz) != JIT_SZ_UNSPEC);                    \
68
      switch ((sz)) {                                   \
69
      case JIT_SZ_8: macro(int8_t); break;              \
70
      case JIT_SZ_16: macro(int16_t); break;            \
71
      case JIT_SZ_32: macro(int32_t); break;            \
72
      case JIT_SZ_64: macro(int64_t); break;            \
73
      default: break;                                   \
74
      }                                                 \
75
   } while (0)
76

77
static void interp_dump_reg(jit_interp_t *state, int64_t ival)
×
78
{
79
   printf("%"PRIx64, ival);
×
80
   if ((ival >= -256 && ival < 0) || (ival >= 10 && ival < 256))
×
81
      printf(" (%"PRIi64")\n", ival);
×
82
   else if (ival >= (intptr_t)state->func->cpool
×
83
            && ival < (intptr_t)state->func->cpool + state->func->cpoolsz) {
×
84
      printf(" ==> cpool pointer\n");
×
85
      jit_hexdump((void *)(intptr_t)ival, 8, 8, NULL, "\t\t\t");
×
86
   }
87
   else {
88
      size_t size;
×
89
      void *base;
×
90
      if ((base = mspace_find(state->mspace, (void *)(intptr_t)ival, &size))) {
×
91
         if (size == 0)
×
92
            nvc_printf("$!red$ ==> bad mspace object$$\n");
×
93
         else {
94
            printf(" ==> %zu byte mspace object\n", size);
×
95
            jit_hexdump(base, size, 8, (void *)(intptr_t)ival, "\t\t\t");
×
96
         }
97
      }
98
      else
99
         printf("\n");
×
100
   }
101
}
×
102

103
static void interp_dump(jit_interp_t *state)
×
104
{
105
   jit_dump_with_mark(state->func, state->pc - 1);
×
106

107
   printf("Arguments:\n");
×
108
   for (int i = 0; i < state->nargs; i++) {
×
109
      printf("\tA%d\t", i);
×
110
      interp_dump_reg(state, state->args[i].integer);
×
111
   }
112

113
   printf("\nRegisters:\n");
×
114
   for (int i = 0; i < state->func->nregs; i++) {
×
115
      printf("\tR%d\t", i);
×
116
      interp_dump_reg(state, state->regs[i].integer);
×
117
   }
118

119
   printf("\nFlags: %c\n", state->flags ? 'T' : 'F');
×
120

121
   if (state->func->framesz > 0) {
×
122
      printf("\nFrame:\n");
×
123
      jit_hexdump(state->frame, state->func->framesz, 16, NULL, "\t");
×
124
   }
125

126
   if (state->func->cpoolsz > 0) {
×
127
      printf("\nConstant pool:\n");
×
128
      jit_hexdump(state->func->cpool, state->func->cpoolsz, 16, NULL, "\t");
×
129
   }
130

131
   jit_thread_local_t *thread = jit_attach_thread(state->anchor);
×
132
   jit_stack_trace_t *trace LOCAL = jit_stack_trace();
×
133

134
   printf("\nCall stack:\n");
×
135

136
   for (int i = 0; i < trace->count; i++)
×
137
      printf("\t%s\n", istr(trace->frames[i].symbol));
×
138

139
   thread->anchor = NULL;
×
140

141
   printf("\n");
×
142
   fflush(stdout);
×
143
}
×
144

145
__attribute__((always_inline))
146
static inline int64_t interp_get_int(jit_interp_t *state, jit_value_t value)
595,620,492✔
147
{
148
   switch (value.kind) {
595,620,492✔
149
   case JIT_VALUE_REG:
448,834,431✔
150
      JIT_ASSERT(value.reg < state->func->nregs);
448,834,431✔
151
      return state->regs[value.reg].integer;
448,834,431✔
152
   case JIT_VALUE_INT64:
146,786,061✔
153
   case JIT_VALUE_DOUBLE:
154
   case JIT_ADDR_ABS:
155
      return value.int64;
146,786,061✔
156
   default:
×
157
      CANNOT_HANDLE(value);
×
158
   }
159
}
160

161
__attribute__((always_inline))
162
static inline double interp_get_real(jit_interp_t *state, jit_value_t value)
3,250,988✔
163
{
164
   switch (value.kind) {
3,250,988✔
165
   case JIT_VALUE_REG:
2,420,593✔
166
      JIT_ASSERT(value.reg < state->func->nregs);
2,420,593✔
167
      return state->regs[value.reg].real;
2,420,593✔
168
   case JIT_VALUE_INT64:
830,395✔
169
   case JIT_VALUE_DOUBLE:
170
      return value.dval;
830,395✔
171
   default:
×
172
      CANNOT_HANDLE(value);
×
173
   }
174
}
175

176
__attribute__((always_inline))
177
static inline void *interp_get_pointer(jit_interp_t *state, jit_value_t value)
184,218,334✔
178
{
179
   switch (value.kind) {
184,218,334✔
180
   case JIT_VALUE_REG:
34,445,951✔
181
      JIT_ASSERT(value.reg < state->func->nregs);
34,445,951✔
182
      return state->regs[value.reg].pointer;
34,445,951✔
183
   case JIT_ADDR_CPOOL:
513,393✔
184
      JIT_ASSERT(value.int64 >= 0 && value.int64 <= state->func->cpoolsz);
513,393✔
185
      return state->func->cpool + value.int64;
513,393✔
186
   case JIT_ADDR_REG:
149,258,990✔
187
      JIT_ASSERT(value.reg < state->func->nregs);
149,258,990✔
188
      return state->regs[value.reg].pointer + value.disp;
149,258,990✔
189
   case JIT_ADDR_ABS:
×
190
      return (void *)(intptr_t)value.int64;
×
191
   default:
×
192
      CANNOT_HANDLE(value);
×
193
   }
194
}
195

196
__attribute__((always_inline))
197
static inline jit_scalar_t interp_get_scalar(jit_interp_t *state,
286,632,423✔
198
                                             jit_value_t value)
199
{
200
   switch (value.kind) {
286,632,423✔
201
   case JIT_VALUE_REG:
230,456,809✔
202
      JIT_ASSERT(value.reg < state->func->nregs);
230,456,809✔
203
      return state->regs[value.reg];
230,456,809✔
204
   case JIT_VALUE_INT64:
54,774,108✔
205
      return (jit_scalar_t){ .integer = value.int64 };
54,774,108✔
206
   case JIT_VALUE_DOUBLE:
325,309✔
207
      return (jit_scalar_t){ .real = value.dval };
325,309✔
208
   case JIT_VALUE_LABEL:
×
209
      return (jit_scalar_t){ .integer = value.label };
×
210
   case JIT_VALUE_HANDLE:
15,232✔
211
      return (jit_scalar_t){ .integer = value.handle };
15,232✔
212
   case JIT_VALUE_LOCUS:
89,938✔
213
      return (jit_scalar_t){ .pointer = value.locus };
89,938✔
214
   case JIT_ADDR_CPOOL:
9,219✔
215
      JIT_ASSERT(value.int64 >= 0 && value.int64 <= state->func->cpoolsz);
9,219✔
216
      return (jit_scalar_t){ .pointer = state->func->cpool + value.int64 };
9,219✔
217
   case JIT_ADDR_REG:
377,082✔
218
      JIT_ASSERT(value.reg < state->func->nregs);
377,082✔
219
      return (jit_scalar_t){
377,082✔
220
         .pointer = state->regs[value.reg].pointer + value.disp
377,082✔
221
      };
222
   case JIT_ADDR_ABS:
584,726✔
223
      return (jit_scalar_t){ .pointer = (void *)(intptr_t)value.int64 };
584,726✔
224
   default:
×
225
      CANNOT_HANDLE(value);
×
226
   }
227
}
228

229
static void interp_recv(jit_interp_t *state, jit_ir_t *ir)
30,679,720✔
230
{
231
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_INT64);
30,679,720✔
232
   const int nth = ir->arg1.int64;
30,679,720✔
233

234
   JIT_ASSERT(nth < JIT_MAX_ARGS);
30,679,720✔
235
   state->regs[ir->result] = state->args[nth];
30,679,720✔
236
   state->nargs = MAX(state->nargs, nth + 1);
30,679,720✔
237
}
30,679,720✔
238

239
static void interp_send(jit_interp_t *state, jit_ir_t *ir)
76,105,604✔
240
{
241
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_INT64);
76,105,604✔
242
   const int nth = ir->arg1.int64;
76,105,604✔
243

244
   JIT_ASSERT(nth < JIT_MAX_ARGS);
76,105,604✔
245
   state->args[nth] = interp_get_scalar(state, ir->arg2);
76,105,604✔
246
   state->nargs = MAX(state->nargs, nth + 1);
76,105,604✔
247
}
76,105,604✔
248

249
static void interp_and(jit_interp_t *state, jit_ir_t *ir)
928,415✔
250
{
251
   const int64_t arg1 = interp_get_int(state, ir->arg1);
928,415✔
252
   const int64_t arg2 = interp_get_int(state, ir->arg2);
928,415✔
253

254
   state->regs[ir->result].integer = arg1 & arg2;
928,415✔
255
}
928,415✔
256

257
static void interp_or(jit_interp_t *state, jit_ir_t *ir)
2,173,896✔
258
{
259
   const int64_t arg1 = interp_get_int(state, ir->arg1);
2,173,896✔
260
   const int64_t arg2 = interp_get_int(state, ir->arg2);
2,173,896✔
261

262
   state->regs[ir->result].integer = arg1 | arg2;
2,173,896✔
263
}
2,173,896✔
264

265
static void interp_xor(jit_interp_t *state, jit_ir_t *ir)
14,763,688✔
266
{
267
   const int64_t arg1 = interp_get_int(state, ir->arg1);
14,763,688✔
268
   const int64_t arg2 = interp_get_int(state, ir->arg2);
14,763,688✔
269

270
   state->regs[ir->result].integer = arg1 ^ arg2;
14,763,688✔
271
}
14,763,688✔
272

273
static void interp_mul(jit_interp_t *state, jit_ir_t *ir)
4,383,141✔
274
{
275
   const int64_t arg1 = interp_get_int(state, ir->arg1);
4,383,141✔
276
   const int64_t arg2 = interp_get_int(state, ir->arg2);
4,383,141✔
277

278
   if (ir->cc == JIT_CC_O) {
4,383,141✔
279
      int overflow = 0;
9,897✔
280

281
#define MUL_OVERFLOW(type) do {                                 \
282
         type i1 = arg1, i2 = arg2, i0;                         \
283
         overflow = __builtin_mul_overflow(i1, i2, &i0);        \
284
         state->regs[ir->result].integer = i0;                  \
285
      } while (0)
286

287
      FOR_EACH_SIZE(ir->size, MUL_OVERFLOW);
9,897✔
288

289
      state->flags = overflow;
9,897✔
290
   }
291
   else if (ir->cc == JIT_CC_C) {
4,373,244✔
292
      int overflow = 0;
381,052✔
293

294
#define UMUL_OVERFLOW(type) do {                                \
295
         u##type i1 = arg1, i2 = arg2, i0;                      \
296
         overflow = __builtin_mul_overflow(i1, i2, &i0);        \
297
         state->regs[ir->result].integer = i0;                  \
298
      } while (0)
299

300
      FOR_EACH_SIZE(ir->size, UMUL_OVERFLOW);
381,052✔
301

302
      state->flags = overflow;
381,052✔
303
   }
304
   else
305
      state->regs[ir->result].integer = arg1 * arg2;
3,992,192✔
306
}
4,383,141✔
307

308
static void interp_fmul(jit_interp_t *state, jit_ir_t *ir)
133,671✔
309
{
310
   const double arg1 = interp_get_real(state, ir->arg1);
133,671✔
311
   const double arg2 = interp_get_real(state, ir->arg2);
133,671✔
312

313
   state->regs[ir->result].real = arg1 * arg2;
133,671✔
314
}
133,671✔
315

316
static void interp_div(jit_interp_t *state, jit_ir_t *ir)
770,591✔
317
{
318
   const int64_t arg1 = interp_get_int(state, ir->arg1);
770,591✔
319
   const int64_t arg2 = interp_get_int(state, ir->arg2);
770,591✔
320

321
   state->regs[ir->result].integer = arg1 / arg2;
770,591✔
322
}
770,591✔
323

324
static void interp_fdiv(jit_interp_t *state, jit_ir_t *ir)
19,496✔
325
{
326
   const double arg1 = interp_get_real(state, ir->arg1);
19,496✔
327
   const double arg2 = interp_get_real(state, ir->arg2);
19,496✔
328

329
   state->regs[ir->result].real = arg1 / arg2;
19,496✔
330
}
19,496✔
331

332
static void interp_sub(jit_interp_t *state, jit_ir_t *ir)
35,664,415✔
333
{
334
   const int64_t arg1 = interp_get_int(state, ir->arg1);
35,664,415✔
335
   const int64_t arg2 = interp_get_int(state, ir->arg2);
35,664,415✔
336

337
   if (ir->cc == JIT_CC_O) {
35,664,415✔
338
      int overflow = 0;
549,944✔
339

340
#define SUB_OVERFLOW(type) do {                                 \
341
         type i1 = arg1, i2 = arg2, i0;                         \
342
         overflow = __builtin_sub_overflow(i1, i2, &i0);        \
343
         state->regs[ir->result].integer = i0;                  \
344
      } while (0)
345

346
      FOR_EACH_SIZE(ir->size, SUB_OVERFLOW);
549,944✔
347

348
      state->flags = overflow;
549,944✔
349
   }
350
   else if (ir->cc == JIT_CC_C) {
35,114,471✔
351
      int overflow = 0;
3✔
352

353
#define USUB_OVERFLOW(type) do {                                \
354
         u##type i1 = arg1, i2 = arg2, i0;                      \
355
         overflow = __builtin_sub_overflow(i1, i2, &i0);        \
356
         state->regs[ir->result].integer = i0;                  \
357
      } while (0)
358

359
      FOR_EACH_SIZE(ir->size, USUB_OVERFLOW);
3✔
360

361
      state->flags = overflow;
3✔
362
   }
363
   else
364
      state->regs[ir->result].integer = arg1 - arg2;
35,114,468✔
365
}
35,664,415✔
366

367
static void interp_fsub(jit_interp_t *state, jit_ir_t *ir)
101,033✔
368
{
369
   const double arg1 = interp_get_real(state, ir->arg1);
101,033✔
370
   const double arg2 = interp_get_real(state, ir->arg2);
101,033✔
371

372
   state->regs[ir->result].real = arg1 - arg2;
101,033✔
373
}
101,033✔
374

375
static void interp_add(jit_interp_t *state, jit_ir_t *ir)
88,978,134✔
376
{
377
   const int64_t arg1 = interp_get_int(state, ir->arg1);
88,978,134✔
378
   const int64_t arg2 = interp_get_int(state, ir->arg2);
88,978,134✔
379

380
   if (ir->cc == JIT_CC_O) {
88,978,134✔
381
      int overflow = 0;
7,266,868✔
382

383
#define ADD_OVERFLOW(type) do {                                 \
384
         type i1 = arg1, i2 = arg2, i0;                         \
385
         overflow = __builtin_add_overflow(i1, i2, &i0);        \
386
         state->regs[ir->result].integer = i0;                  \
387
      } while (0)
388

389
      FOR_EACH_SIZE(ir->size, ADD_OVERFLOW);
7,266,868✔
390

391
      state->flags = overflow;
7,266,868✔
392
   }
393
   else if (ir->cc == JIT_CC_C) {
81,711,266✔
394
      int overflow = 0;
381,052✔
395

396
#define UADD_OVERFLOW(type) do {                                \
397
         u##type i1 = arg1, i2 = arg2, i0;                      \
398
         overflow = __builtin_add_overflow(i1, i2, &i0);        \
399
         state->regs[ir->result].integer = i0;                  \
400
      } while (0)
401

402
      FOR_EACH_SIZE(ir->size, UADD_OVERFLOW);
381,052✔
403

404
      state->flags = overflow;
381,052✔
405
   }
406
   else
407
      state->regs[ir->result].integer = arg1 + arg2;
81,330,214✔
408
}
88,978,134✔
409

410
static void interp_fadd(jit_interp_t *state, jit_ir_t *ir)
98,104✔
411
{
412
   const double arg1 = interp_get_real(state, ir->arg1);
98,104✔
413
   const double arg2 = interp_get_real(state, ir->arg2);
98,104✔
414

415
   state->regs[ir->result].real = arg1 + arg2;
98,104✔
416
}
98,104✔
417

418
static void interp_shl(jit_interp_t *state, jit_ir_t *ir)
11,256,024✔
419
{
420
   const uint64_t arg1 = interp_get_int(state, ir->arg1);
11,256,024✔
421
   const uint64_t arg2 = interp_get_int(state, ir->arg2);
11,256,024✔
422

423
   state->regs[ir->result].integer = arg2 < 64 ? arg1 << arg2 : 0;
11,256,024✔
424
}
11,256,024✔
425

426
static void interp_shr(jit_interp_t *state, jit_ir_t *ir)
987✔
427
{
428
   const uint64_t arg1 = interp_get_int(state, ir->arg1);
987✔
429
   const uint64_t arg2 = interp_get_int(state, ir->arg2);
987✔
430

431
   state->regs[ir->result].integer = arg2 < 64 ? arg1 >> arg2 : 0;
987✔
432
}
987✔
433

434
static void interp_asr(jit_interp_t *state, jit_ir_t *ir)
11,884,202✔
435
{
436
   const int64_t arg1 = interp_get_int(state, ir->arg1);
11,884,202✔
437
   const int64_t arg2 = interp_get_int(state, ir->arg2);
11,884,202✔
438

439
   if (arg2 < 64)
11,884,202✔
440
      state->regs[ir->result].integer = arg1 >> arg2;
11,884,202✔
441
   else
442
      state->regs[ir->result].integer = arg1 < 0 ? -1 : 0;
×
443
}
11,884,202✔
444

445
static void interp_store(jit_interp_t *state, jit_ir_t *ir)
47,286,906✔
446
{
447
   jit_scalar_t arg1 = interp_get_scalar(state, ir->arg1);
47,286,906✔
448
   void *arg2 = interp_get_pointer(state, ir->arg2);
47,286,906✔
449

450
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
47,286,906✔
451
   JIT_ASSERT(arg2 != NULL);
47,286,906✔
452
   JIT_ASSERT((intptr_t)arg2 >= 4096);
47,286,906✔
453

454
   switch (ir->size) {
47,286,906✔
455
   case JIT_SZ_8:
12,506,100✔
456
      unaligned_store(arg2, arg1.integer, uint8_t);
12,506,100✔
457
      break;
12,506,100✔
458
   case JIT_SZ_16:
2,287✔
459
      unaligned_store(arg2, arg1.integer, uint16_t);
2,287✔
460
      break;
2,287✔
461
   case JIT_SZ_32:
23,694,047✔
462
      unaligned_store(arg2, arg1.integer, uint32_t);
23,694,047✔
463
      break;
23,694,047✔
464
   case JIT_SZ_64:
11,084,472✔
465
      unaligned_store(arg2, arg1.integer, uint64_t);
11,084,472✔
466
      break;
11,084,472✔
467
   case JIT_SZ_UNSPEC:
×
468
      should_not_reach_here();
469
   }
470
}
47,286,906✔
471

472
static void interp_uload(jit_interp_t *state, jit_ir_t *ir)
15,137,064✔
473
{
474
   void *arg1 = interp_get_pointer(state, ir->arg1);
15,137,064✔
475

476
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
15,137,064✔
477
   JIT_ASSERT(arg1 != NULL);
15,137,064✔
478
   JIT_ASSERT((intptr_t)arg1 >= 4096);
15,137,064✔
479

480
   switch (ir->size) {
15,137,064✔
481
   case JIT_SZ_8:
15,136,958✔
482
      state->regs[ir->result].integer = *(uint8_t *)arg1;
15,136,958✔
483
      break;
15,136,958✔
484
   case JIT_SZ_16:
13✔
485
      state->regs[ir->result].integer = *(uint16_t *)arg1;
13✔
486
      break;
13✔
487
   case JIT_SZ_32:
63✔
488
      state->regs[ir->result].integer = *(uint32_t *)arg1;
63✔
489
      break;
63✔
490
   case JIT_SZ_64:
30✔
491
      state->regs[ir->result].integer = *(uint64_t *)arg1;
30✔
492
      break;
30✔
493
   case JIT_SZ_UNSPEC:
494
      break;
495
   }
496
}
15,137,064✔
497

498
static void interp_load(jit_interp_t *state, jit_ir_t *ir)
87,432,292✔
499
{
500
   void *arg1 = interp_get_pointer(state, ir->arg1);
87,432,292✔
501

502
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
87,432,292✔
503
   JIT_ASSERT(arg1 != NULL);
87,432,292✔
504
   JIT_ASSERT((intptr_t)arg1 >= 4096);
87,432,292✔
505

506
   switch (ir->size) {
87,432,292✔
507
   case JIT_SZ_8:
21✔
508
      state->regs[ir->result].integer = *(int8_t *)arg1;
21✔
509
      break;
21✔
510
   case JIT_SZ_16:
×
511
      state->regs[ir->result].integer = *(int16_t *)arg1;
×
512
      break;
×
513
   case JIT_SZ_32:
36,943,325✔
514
      state->regs[ir->result].integer = *(int32_t *)arg1;
36,943,325✔
515
      break;
36,943,325✔
516
   case JIT_SZ_64:
50,488,946✔
517
      state->regs[ir->result].integer = *(int64_t *)arg1;
50,488,946✔
518
      break;
50,488,946✔
519
   case JIT_SZ_UNSPEC:
520
      break;
521
   }
522
}
87,432,292✔
523

524
static void interp_cmp(jit_interp_t *state, jit_ir_t *ir)
88,041,773✔
525
{
526
   const int64_t arg1 = interp_get_int(state, ir->arg1);
88,041,773✔
527
   const int64_t arg2 = interp_get_int(state, ir->arg2);
88,041,773✔
528

529
   switch (ir->cc) {
88,041,773✔
530
   case JIT_CC_EQ: state->flags = (arg1 == arg2); break;
33,761,449✔
531
   case JIT_CC_NE: state->flags = (arg1 != arg2); break;
12,132,553✔
532
   case JIT_CC_LT: state->flags = (arg1 < arg2); break;
27,054,571✔
533
   case JIT_CC_GT: state->flags = (arg1 > arg2); break;
4,450,521✔
534
   case JIT_CC_LE: state->flags = (arg1 <= arg2); break;
11,086✔
535
   case JIT_CC_GE: state->flags = (arg1 >= arg2); break;
10,631,593✔
536
   default: state->flags = 0; break;
×
537
   }
538
}
88,041,773✔
539

540
static void interp_ccmp(jit_interp_t *state, jit_ir_t *ir)
10,783,993✔
541
{
542
   const int64_t arg1 = interp_get_int(state, ir->arg1);
10,783,993✔
543
   const int64_t arg2 = interp_get_int(state, ir->arg2);
10,783,993✔
544

545
   switch (ir->cc) {
10,783,993✔
546
   case JIT_CC_EQ: state->flags &= (arg1 == arg2); break;
219,633✔
547
   case JIT_CC_NE: state->flags &= (arg1 != arg2); break;
×
548
   case JIT_CC_LT: state->flags &= (arg1 < arg2); break;
50,630✔
549
   case JIT_CC_GT: state->flags &= (arg1 > arg2); break;
42,524✔
550
   case JIT_CC_LE: state->flags &= (arg1 <= arg2); break;
10,471,206✔
551
   case JIT_CC_GE: state->flags &= (arg1 >= arg2); break;
×
552
   default: state->flags = 0; break;
×
553
   }
554
}
10,783,993✔
555

556
static void interp_fcmp(jit_interp_t *state, jit_ir_t *ir)
730,032✔
557
{
558
   const double arg1 = interp_get_real(state, ir->arg1);
730,032✔
559
   const double arg2 = interp_get_real(state, ir->arg2);
730,032✔
560

561
   switch (ir->cc) {
730,032✔
562
   case JIT_CC_EQ: state->flags = (arg1 == arg2); break;
76,870✔
563
   case JIT_CC_NE: state->flags = (arg1 != arg2); break;
33✔
564
   case JIT_CC_LT: state->flags = (arg1 < arg2); break;
135,982✔
565
   case JIT_CC_GT: state->flags = (arg1 > arg2); break;
11,470✔
566
   case JIT_CC_LE: state->flags = (arg1 <= arg2); break;
398✔
567
   case JIT_CC_GE: state->flags = (arg1 >= arg2); break;
505,279✔
568
   default: state->flags = 0; break;
×
569
   }
570
}
730,032✔
571

572
static void interp_fccmp(jit_interp_t *state, jit_ir_t *ir)
146,395✔
573
{
574
   const double arg1 = interp_get_real(state, ir->arg1);
146,395✔
575
   const double arg2 = interp_get_real(state, ir->arg2);
146,395✔
576

577
   switch (ir->cc) {
146,395✔
578
   case JIT_CC_EQ: state->flags &= (arg1 == arg2); break;
×
579
   case JIT_CC_NE: state->flags &= (arg1 != arg2); break;
×
580
   case JIT_CC_LT: state->flags &= (arg1 < arg2); break;
×
581
   case JIT_CC_GT: state->flags &= (arg1 > arg2); break;
×
582
   case JIT_CC_LE: state->flags &= (arg1 <= arg2); break;
146,395✔
583
   case JIT_CC_GE: state->flags &= (arg1 >= arg2); break;
×
584
   default: state->flags = 0; break;
×
585
   }
586
}
146,395✔
587

588
static void interp_rem(jit_interp_t *state, jit_ir_t *ir)
785,453✔
589
{
590
   const int64_t x = interp_get_int(state, ir->arg1);
785,453✔
591
   const int64_t y = interp_get_int(state, ir->arg2);
785,453✔
592

593
   state->regs[ir->result].integer = x - (x / y) * y;
785,453✔
594
}
785,453✔
595

596
static void interp_clamp(jit_interp_t *state, jit_ir_t *ir)
6,161,270✔
597
{
598
   const int64_t value = interp_get_int(state, ir->arg1);
6,161,270✔
599

600
   state->regs[ir->result].integer = value < 0 ? 0 : value;
6,161,270✔
601
}
6,161,270✔
602

603
static void interp_cset(jit_interp_t *state, jit_ir_t *ir)
39,146,471✔
604
{
605
   state->regs[ir->result].integer = !!(state->flags);
39,146,471✔
606
}
39,146,471✔
607

608
static void interp_branch_to(jit_interp_t *state, jit_value_t label)
63,313,149✔
609
{
610
   JIT_ASSERT(label.kind == JIT_VALUE_LABEL);
63,313,149✔
611
   state->pc = label.label;
63,313,149✔
612
   JIT_ASSERT(state->pc < state->func->nirs);
63,313,149✔
613
}
63,313,149✔
614

615
static void interp_jump(jit_interp_t *state, jit_ir_t *ir)
84,779,796✔
616
{
617
   switch (ir->cc) {
84,779,796✔
618
   case JIT_CC_NONE:
22,560,017✔
619
      interp_branch_to(state, ir->arg1);
22,560,017✔
620
      break;
22,560,017✔
621
   case JIT_CC_T:
44,142,748✔
622
      if (state->flags)
44,142,748✔
623
         interp_branch_to(state, ir->arg1);
22,912,842✔
624
      break;
625
   case JIT_CC_F:
18,077,031✔
626
      if (!state->flags)
18,077,031✔
627
         interp_branch_to(state, ir->arg1);
17,581,471✔
628
      break;
629
   default:
×
630
      interp_dump(state);
×
631
      fatal_trace("unhandled jump condition code");
632
   }
633
}
84,779,796✔
634

635
static void interp_trap(jit_interp_t *state, jit_ir_t *ir)
×
636
{
637
   interp_dump(state);
×
638
   fatal_trace("executed trap opcode");
639
}
640

641
static void interp_call(jit_interp_t *state, jit_ir_t *ir)
11,713,997✔
642
{
643
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_HANDLE);
11,713,997✔
644

645
   state->anchor->irpos = ir - state->func->irbuf;
11,713,997✔
646

647
   if (ir->arg1.handle == JIT_HANDLE_INVALID) {
11,713,997✔
648
      jit_dump_with_mark(state->func, state->anchor->irpos);
×
649
      jit_msg(NULL, DIAG_FATAL, "missing definition for subprogram");
×
650
   }
651
   else {
652
      jit_func_t *f = jit_get_func(state->func->jit, ir->arg1.handle);
11,713,997✔
653
      jit_entry_fn_t entry = load_acquire(&f->entry);
11,713,997✔
654
      (*entry)(f, state->anchor, state->args, state->tlab);
11,713,997✔
655
   }
656
}
11,712,980✔
657

658
static void interp_mov(jit_interp_t *state, jit_ir_t *ir)
163,082,463✔
659
{
660
   state->regs[ir->result] = interp_get_scalar(state, ir->arg1);
163,082,463✔
661
}
163,082,463✔
662

663
static void interp_csel(jit_interp_t *state, jit_ir_t *ir)
41,342,089✔
664
{
665
   if (state->flags)
41,342,089✔
666
      state->regs[ir->result].integer = interp_get_int(state, ir->arg1);
48,421,302✔
667
   else
668
      state->regs[ir->result].integer = interp_get_int(state, ir->arg2);
34,262,876✔
669
}
41,342,089✔
670

671
static void interp_neg(jit_interp_t *state, jit_ir_t *ir)
2,087,198✔
672
{
673
   state->regs[ir->result].integer = -interp_get_int(state, ir->arg1);
2,087,198✔
674
}
2,087,198✔
675

676
static void interp_fneg(jit_interp_t *state, jit_ir_t *ir)
60,755✔
677
{
678
   state->regs[ir->result].real = -interp_get_real(state, ir->arg1);
60,755✔
679
}
60,755✔
680

681
static void interp_not(jit_interp_t *state, jit_ir_t *ir)
740,169✔
682
{
683
   state->regs[ir->result].integer = !interp_get_int(state, ir->arg1);
740,169✔
684
}
740,169✔
685

686
static void interp_scvtf(jit_interp_t *state, jit_ir_t *ir)
376,818✔
687
{
688
   state->regs[ir->result].real = interp_get_int(state, ir->arg1);
376,818✔
689
}
376,818✔
690

691
static void interp_fcvtns(jit_interp_t *state, jit_ir_t *ir)
9,037✔
692
{
693
   const double f = interp_get_real(state, ir->arg1);
9,037✔
694
   state->regs[ir->result].integer = (int64_t)(f + copysign(0.5, f));
9,037✔
695
}
9,037✔
696

697
static void interp_lea(jit_interp_t *state, jit_ir_t *ir)
23,122,032✔
698
{
699
   state->regs[ir->result].pointer = interp_get_pointer(state, ir->arg1);
23,122,032✔
700
}
23,122,032✔
701

702
static void interp_fexp(jit_interp_t *state, jit_ir_t *ir)
361,867✔
703
{
704
   const double x = interp_get_real(state, ir->arg1);
361,867✔
705
   const double y = interp_get_real(state, ir->arg2);
361,867✔
706

707
   state->regs[ir->result].real = pow(x, y);
361,867✔
708
}
361,867✔
709

710
static void interp_exp(jit_interp_t *state, jit_ir_t *ir)
200✔
711
{
712
   const int64_t x = interp_get_int(state, ir->arg1);
200✔
713
   const int64_t y = interp_get_int(state, ir->arg2);
200✔
714

715
   if (ir->cc == JIT_CC_O) {
200✔
716
      int overflow = 0, xo = 0;
185✔
717

718
#define EXP_OVERFLOW(type) do {                                         \
719
         type xt = x, yt = y, r = 1;                                    \
720
         while (yt) {                                                   \
721
            if (yt & 1)                                                 \
722
               overflow |= xo || __builtin_mul_overflow(r, xt, &r);     \
723
            yt >>= 1;                                                   \
724
            xo |= __builtin_mul_overflow(xt, xt, &xt);                  \
725
         }                                                              \
726
         state->regs[ir->result].integer = r;                           \
727
      } while (0)
728

729
      FOR_EACH_SIZE(ir->size, EXP_OVERFLOW);
697✔
730

731
      state->flags = overflow;
185✔
732
   }
733
   else if (ir->cc == JIT_CC_C) {
15✔
734
      int overflow = 0, xo = 0;
14✔
735

736
#define UEXP_OVERFLOW(type) do {                                        \
737
         u##type xt = x, yt = y, r = 1;                                 \
738
         while (yt) {                                                   \
739
            if (yt & 1)                                                 \
740
               overflow |= xo || __builtin_mul_overflow(r, xt, &r);     \
741
            yt >>= 1;                                                   \
742
            xo |= __builtin_mul_overflow(xt, xt, &xt);                  \
743
         }                                                              \
744
         state->regs[ir->result].integer = r;                           \
745
      } while (0)
746

747
      FOR_EACH_SIZE(ir->size, UEXP_OVERFLOW);
69✔
748

749
      state->flags = overflow;
14✔
750
   }
751
   else
752
      state->regs[ir->result].integer = ipow(x, y);
1✔
753
}
200✔
754

755
static void interp_copy(jit_interp_t *state, jit_ir_t *ir)
446,594✔
756
{
757
   const size_t count = state->regs[ir->result].integer;
446,594✔
758
   void *dest = interp_get_pointer(state, ir->arg1);
446,594✔
759
   const void *src = interp_get_pointer(state, ir->arg2);
446,594✔
760

761
   JIT_ASSERT((uintptr_t)dest >= 4096 || count == 0);
446,594✔
762
   JIT_ASSERT((uintptr_t)src >= 4096 || count == 0);
446,594✔
763
   JIT_ASSERT(dest + count <= src || src + count <= dest);
446,594✔
764

765
   memcpy(dest, src, count);
446,594✔
766
}
446,594✔
767

768
static void interp_move(jit_interp_t *state, jit_ir_t *ir)
3,928,096✔
769
{
770
   const size_t count = state->regs[ir->result].integer;
3,928,096✔
771
   void *dest = interp_get_pointer(state, ir->arg1);
3,928,096✔
772
   const void *src = interp_get_pointer(state, ir->arg2);
3,928,096✔
773

774
   JIT_ASSERT((uintptr_t)dest >= 4096 || count == 0);
3,928,096✔
775
   JIT_ASSERT((uintptr_t)src >= 4096 || count == 0);
3,928,096✔
776

777
   memmove(dest, src, count);
3,928,096✔
778
}
3,928,096✔
779

780
static void interp_bzero(jit_interp_t *state, jit_ir_t *ir)
1,647,162✔
781
{
782
   const size_t count = state->regs[ir->result].integer;
1,647,162✔
783
   void *dest = interp_get_pointer(state, ir->arg1);
1,647,162✔
784

785
   memset(dest, '\0', count);
1,647,162✔
786
}
1,647,162✔
787

788
static void interp_memset(jit_interp_t *state, jit_ir_t *ir)
456,937✔
789
{
790
   const size_t bytes = state->regs[ir->result].integer;
456,937✔
791
   void *dest = interp_get_pointer(state, ir->arg1);
456,937✔
792
   const uint64_t value = interp_get_int(state, ir->arg2);
456,937✔
793

794
   JIT_ASSERT(dest != NULL);
456,937✔
795

796
#define MEMSET_LOOP(type) do {                      \
797
      JIT_ASSERT(bytes % sizeof(type) == 0);        \
798
      type *eptr = dest + bytes;                    \
799
      for (type *p = dest; p < eptr; p++)           \
800
         *p = value;                                \
801
   } while (0)
802

803
   FOR_EACH_SIZE(ir->size, MEMSET_LOOP);
179,370,130✔
804
}
456,937✔
805

806
static void interp_galloc(jit_interp_t *state, jit_ir_t *ir)
254,180✔
807
{
808
   jit_thread_local_t *thread = jit_thread_local();
254,180✔
809
   thread->anchor = state->anchor;
254,180✔
810

811
   state->anchor->irpos = ir - state->func->irbuf;
254,180✔
812

813
   uint64_t bytes = interp_get_int(state, ir->arg1);
254,180✔
814

815
   if (bytes > UINT32_MAX)
254,180✔
816
      jit_msg(NULL, DIAG_FATAL, "attempting to allocate %"PRIu64" byte object "
3✔
817
              "which is larger than the maximum supported %u bytes",
818
              bytes, UINT32_MAX);
819
   else if (bytes == 0)
254,177✔
820
      bytes = 1;   // Never return a NULL pointer
821

822
   state->regs[ir->result].pointer = mspace_alloc(state->mspace, bytes);
254,177✔
823

824
   thread->anchor = NULL;
254,173✔
825
}
254,173✔
826

827
static void interp_lalloc(jit_interp_t *state, jit_ir_t *ir)
2,461,868✔
828
{
829
   jit_thread_local_t *thread = jit_thread_local();
2,461,868✔
830
   thread->anchor = state->anchor;
2,461,868✔
831

832
   state->anchor->irpos = ir - state->func->irbuf;
2,461,868✔
833

834
   const size_t bytes = interp_get_int(state, ir->arg1);
2,461,868✔
835
   state->regs[ir->result].pointer = tlab_alloc(state->tlab, bytes);
2,461,868✔
836

837
   thread->anchor = NULL;
2,461,868✔
838
}
2,461,868✔
839

840
static void interp_salloc(jit_interp_t *state, jit_ir_t *ir)
6,720,320✔
841
{
842
   assert(ir->arg1.int64 + ir->arg2.int64 <= state->func->framesz);
6,720,320✔
843
   state->regs[ir->result].pointer = state->frame + ir->arg1.int64;
6,720,320✔
844
}
6,720,320✔
845

846
static void interp_exit(jit_interp_t *state, jit_ir_t *ir)
3,951,792✔
847
{
848
   state->anchor->irpos = ir - state->func->irbuf;
3,951,792✔
849
   __nvc_do_exit(ir->arg1.exit, state->anchor, state->args, state->tlab);
3,951,792✔
850
}
3,950,703✔
851

852
static void interp_getpriv(jit_interp_t *state, jit_ir_t *ir)
4,035,725✔
853
{
854
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_HANDLE);
4,035,725✔
855
   jit_func_t *f = jit_get_func(state->func->jit, ir->arg1.handle);
4,035,725✔
856
   void *ptr = load_acquire(jit_get_privdata_ptr(state->func->jit, f));
4,035,725✔
857
   state->regs[ir->result].pointer = ptr;
4,035,725✔
858
}
4,035,725✔
859

860
static void interp_putpriv(jit_interp_t *state, jit_ir_t *ir)
15,303✔
861
{
862
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_HANDLE);
15,303✔
863
   jit_func_t *f = jit_get_func(state->func->jit, ir->arg1.handle);
15,303✔
864
   void *ptr = interp_get_pointer(state, ir->arg2);
15,303✔
865
   store_release(jit_get_privdata_ptr(state->func->jit, f), ptr);
15,303✔
866
}
15,303✔
867

868
static void interp_case(jit_interp_t *state, jit_ir_t *ir)
538,881✔
869
{
870
   jit_scalar_t test = state->regs[ir->result];
538,881✔
871
   const int64_t cmp = interp_get_int(state, ir->arg1);
538,881✔
872

873
   if (test.integer == cmp)
538,881✔
874
      interp_branch_to(state, ir->arg2);
258,819✔
875
}
538,881✔
876

877
static void interp_trim(jit_interp_t *state, jit_ir_t *ir)
520,859✔
878
{
879
   assert(state->tlab->alloc >= state->anchor->watermark);
520,859✔
880
   state->tlab->alloc = state->anchor->watermark;
520,859✔
881
}
520,859✔
882

883
static void interp_reexec(jit_interp_t *state, jit_ir_t *ir)
1,449✔
884
{
885
   jit_entry_fn_t entry = load_acquire(&state->func->entry);
1,449✔
886
   (*entry)(state->func, state->anchor->caller, state->args, state->tlab);
1,449✔
887
}
1,273✔
888

889
static void interp_sadd(jit_interp_t *state, jit_ir_t *ir)
3,921✔
890
{
891
   const void *ptr = interp_get_pointer(state, ir->arg1);
3,921✔
892
   const int64_t addend = interp_get_int(state, ir->arg2);
3,921✔
893

894
   JIT_ASSERT(ptr != NULL);
3,921✔
895
   JIT_ASSERT((intptr_t)ptr >= 4096);
3,921✔
896

897
#define SADD(type) do {                                         \
898
      u##type cur = *(u##type *)ptr;                            \
899
      *(u##type *)ptr = saturate_add(cur, addend);              \
900
   } while (0)
901

902
   FOR_EACH_SIZE(ir->size, SADD);
3,921✔
903
}
3,921✔
904

905
static void interp_pack(jit_interp_t *state, jit_ir_t *ir)
367,337✔
906
{
907
   const uint8_t *src = interp_get_pointer(state, ir->arg1);
367,337✔
908
   const int size = interp_get_int(state, ir->arg2);
367,337✔
909
   __nvc_pack(src, size, state->args);
367,337✔
910
}
367,337✔
911

912
static void interp_unpack(jit_interp_t *state, jit_ir_t *ir)
78,725✔
913
{
914
   jit_scalar_t aval = interp_get_scalar(state, ir->arg1);
78,725✔
915
   jit_scalar_t bval = interp_get_scalar(state, ir->arg2);
78,725✔
916
   __nvc_unpack(aval, bval, state->args);
78,725✔
917
}
78,725✔
918

919
static void interp_vec4op(jit_interp_t *state, jit_ir_t *ir)
3,036✔
920
{
921
   state->anchor->irpos = ir - state->func->irbuf;
3,036✔
922
   __nvc_vec4op(ir->arg1.int64, state->anchor, state->args, ir->arg2.int64);
3,036✔
923
}
3,036✔
924

925
static void interp_loop(jit_interp_t *state)
4,340,887✔
926
{
927
   for (;;) {
1,426,438,711✔
928
      JIT_ASSERT(state->pc < state->func->nirs);
1,426,438,711✔
929
      jit_ir_t *ir = &(state->func->irbuf[state->pc++]);
1,426,438,711✔
930
      switch (ir->op) {
1,426,438,711✔
931
      case J_RECV:
30,679,720✔
932
         interp_recv(state, ir);
30,679,720✔
933
         break;
30,679,720✔
934
      case J_SEND:
76,105,604✔
935
         interp_send(state, ir);
76,105,604✔
936
         break;
76,105,604✔
937
      case J_AND:
928,415✔
938
         interp_and(state, ir);
928,415✔
939
         break;
928,415✔
940
      case J_OR:
2,173,896✔
941
         interp_or(state, ir);
2,173,896✔
942
         break;
2,173,896✔
943
      case J_XOR:
14,763,688✔
944
         interp_xor(state, ir);
14,763,688✔
945
         break;
14,763,688✔
946
      case J_SUB:
35,664,415✔
947
         interp_sub(state, ir);
35,664,415✔
948
         break;
35,664,415✔
949
      case J_FSUB:
101,033✔
950
         interp_fsub(state, ir);
101,033✔
951
         break;
101,033✔
952
      case J_ADD:
88,978,134✔
953
         interp_add(state, ir);
88,978,134✔
954
         break;
88,978,134✔
955
      case J_FADD:
98,104✔
956
         interp_fadd(state, ir);
98,104✔
957
         break;
98,104✔
958
      case J_MUL:
4,383,141✔
959
         interp_mul(state, ir);
4,383,141✔
960
         break;
4,383,141✔
961
      case J_FMUL:
133,671✔
962
         interp_fmul(state, ir);
133,671✔
963
         break;
133,671✔
964
      case J_DIV:
770,591✔
965
         interp_div(state, ir);
770,591✔
966
         break;
770,591✔
967
      case J_FDIV:
19,496✔
968
         interp_fdiv(state, ir);
19,496✔
969
         break;
19,496✔
970
      case J_SHL:
11,256,024✔
971
         interp_shl(state, ir);
11,256,024✔
972
         break;
11,256,024✔
973
      case J_SHR:
987✔
974
         interp_shr(state, ir);
987✔
975
         break;
987✔
976
      case J_ASR:
11,884,202✔
977
         interp_asr(state, ir);
11,884,202✔
978
         break;
11,884,202✔
979
      case J_RET:
980
         return;
981
      case J_STORE:
47,286,906✔
982
         interp_store(state, ir);
47,286,906✔
983
         break;
47,286,906✔
984
      case J_ULOAD:
15,137,064✔
985
         interp_uload(state, ir);
15,137,064✔
986
         break;
15,137,064✔
987
      case J_LOAD:
87,432,292✔
988
         interp_load(state, ir);
87,432,292✔
989
         break;
87,432,292✔
990
      case J_CMP:
88,041,773✔
991
         interp_cmp(state, ir);
88,041,773✔
992
         break;
88,041,773✔
993
      case J_CCMP:
10,783,993✔
994
         interp_ccmp(state, ir);
10,783,993✔
995
         break;
10,783,993✔
996
      case J_FCMP:
730,032✔
997
         interp_fcmp(state, ir);
730,032✔
998
         break;
730,032✔
999
      case J_FCCMP:
146,395✔
1000
         interp_fccmp(state, ir);
146,395✔
1001
         break;
146,395✔
1002
      case J_CSET:
39,146,471✔
1003
         interp_cset(state, ir);
39,146,471✔
1004
         break;
39,146,471✔
1005
      case J_JUMP:
84,779,796✔
1006
         interp_jump(state, ir);
84,779,796✔
1007
         break;
84,779,796✔
1008
      case J_TRAP:
×
1009
         interp_trap(state, ir);
×
1010
         break;
1011
      case J_CALL:
11,713,997✔
1012
         interp_call(state, ir);
11,713,997✔
1013
         break;
11,713,997✔
1014
      case J_MOV:
163,082,463✔
1015
         interp_mov(state, ir);
163,082,463✔
1016
         break;
163,082,463✔
1017
      case J_CSEL:
41,342,089✔
1018
         interp_csel(state, ir);
41,342,089✔
1019
         break;
41,342,089✔
1020
      case J_NEG:
2,087,198✔
1021
         interp_neg(state, ir);
2,087,198✔
1022
         break;
2,087,198✔
1023
      case J_FNEG:
60,755✔
1024
         interp_fneg(state, ir);
60,755✔
1025
         break;
60,755✔
1026
      case J_NOT:
740,169✔
1027
         interp_not(state, ir);
740,169✔
1028
         break;
740,169✔
1029
      case J_SCVTF:
376,818✔
1030
         interp_scvtf(state, ir);
376,818✔
1031
         break;
376,818✔
1032
      case J_FCVTNS:
9,037✔
1033
         interp_fcvtns(state, ir);
9,037✔
1034
         break;
9,037✔
1035
      case J_LEA:
23,122,032✔
1036
         interp_lea(state, ir);
23,122,032✔
1037
         break;
23,122,032✔
1038
      case J_REM:
785,453✔
1039
         interp_rem(state, ir);
785,453✔
1040
         break;
785,453✔
1041
      case J_CLAMP:
6,161,270✔
1042
         interp_clamp(state, ir);
6,161,270✔
1043
         break;
6,161,270✔
1044
      case J_DEBUG:
1045
      case J_NOP:
1046
         break;
1047
      case MACRO_COPY:
446,594✔
1048
         interp_copy(state, ir);
446,594✔
1049
         break;
446,594✔
1050
      case MACRO_MOVE:
3,928,096✔
1051
         interp_move(state, ir);
3,928,096✔
1052
         break;
3,928,096✔
1053
      case MACRO_BZERO:
1,647,162✔
1054
         interp_bzero(state, ir);
1,647,162✔
1055
         break;
1,647,162✔
1056
      case MACRO_MEMSET:
456,937✔
1057
         interp_memset(state, ir);
456,937✔
1058
         break;
456,937✔
1059
      case MACRO_GALLOC:
254,180✔
1060
         interp_galloc(state, ir);
254,180✔
1061
         break;
254,180✔
1062
      case MACRO_LALLOC:
2,461,868✔
1063
         interp_lalloc(state, ir);
2,461,868✔
1064
         break;
2,461,868✔
1065
      case MACRO_SALLOC:
6,720,320✔
1066
         interp_salloc(state, ir);
6,720,320✔
1067
         break;
6,720,320✔
1068
      case MACRO_EXIT:
3,951,792✔
1069
         interp_exit(state, ir);
3,951,792✔
1070
         break;
3,951,792✔
1071
      case MACRO_FEXP:
361,867✔
1072
         interp_fexp(state, ir);
361,867✔
1073
         break;
361,867✔
1074
      case MACRO_EXP:
200✔
1075
         interp_exp(state, ir);
200✔
1076
         break;
200✔
1077
      case MACRO_GETPRIV:
4,035,725✔
1078
         interp_getpriv(state, ir);
4,035,725✔
1079
         break;
4,035,725✔
1080
      case MACRO_PUTPRIV:
15,303✔
1081
         interp_putpriv(state, ir);
15,303✔
1082
         break;
15,303✔
1083
      case MACRO_CASE:
538,881✔
1084
         interp_case(state, ir);
538,881✔
1085
         break;
538,881✔
1086
      case MACRO_TRIM:
520,859✔
1087
         interp_trim(state, ir);
520,859✔
1088
         break;
520,859✔
1089
      case MACRO_REEXEC:
1,449✔
1090
         interp_reexec(state, ir);
1,449✔
1091
         return;
1,449✔
1092
      case MACRO_SADD:
3,921✔
1093
         interp_sadd(state, ir);
3,921✔
1094
         break;
3,921✔
1095
      case MACRO_PACK:
367,337✔
1096
         interp_pack(state, ir);
367,337✔
1097
         break;
367,337✔
1098
      case MACRO_UNPACK:
78,725✔
1099
         interp_unpack(state, ir);
78,725✔
1100
         break;
78,725✔
1101
      case MACRO_VEC4OP:
3,036✔
1102
         interp_vec4op(state, ir);
3,036✔
1103
         break;
3,036✔
1104
      default:
×
1105
         interp_dump(state);
×
1106
         fatal_trace("cannot interpret opcode %s", jit_op_name(ir->op));
1107
      }
1108
   }
1109
}
1110

1111
void jit_interp(jit_func_t *f, jit_anchor_t *caller, jit_scalar_t *args,
4,340,892✔
1112
                tlab_t *tlab)
1113
{
4,340,892✔
1114
   jit_entry_fn_t entry = load_acquire(&f->entry);
4,340,892✔
1115
   if (unlikely(entry != jit_interp)) {
4,340,892✔
1116
      // Raced with a code generation thread installing a compiled
1117
      // version of this function
1118
      return (*entry)(f, caller, args, tlab);
×
1119
   }
1120

1121
   jit_fill_irbuf(f);
4,340,892✔
1122

1123
   if (f->next_tier && --(f->hotness) <= 0)
4,340,887✔
1124
      jit_tier_up(f);
14,933✔
1125

1126
   jit_anchor_t anchor = {
4,340,887✔
1127
      .caller    = caller,
1128
      .func      = f,
1129
      .watermark = tlab->alloc,
4,340,887✔
1130
   };
1131

1132
   // Using VLAs here as we need these allocated on the stack so the
1133
   // mspace GC can scan them
1134
   jit_scalar_t regs[f->nregs + 1];
4,340,887✔
1135
   unsigned char frame[f->framesz + 1];
4,340,887✔
1136

1137
#ifdef DEBUG
1138
   memset(regs, 0xde, sizeof(jit_scalar_t) * f->nregs);
4,340,887✔
1139
   memset(frame, 0xde, f->framesz);
4,340,887✔
1140
#endif
1141

1142
   jit_interp_t state = {
4,340,887✔
1143
      .args     = args,
1144
      .regs     = regs,
1145
      .nargs    = 0,
1146
      .pc       = 0,
1147
      .func     = f,
1148
      .frame    = frame,
1149
      .mspace   = jit_get_mspace(f->jit),
4,340,887✔
1150
      .anchor   = &anchor,
1151
      .tlab     = tlab,
1152
   };
1153

1154
   interp_loop(&state);
4,340,887✔
1155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc