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

nickg / nvc / 23163104024

16 Mar 2026 07:48PM UTC coverage: 92.479% (-0.003%) from 92.482%
23163104024

push

github

nickg
Correct size and sign extension rules for Verilog case statement

83 of 87 new or added lines in 4 files covered. (95.4%)

8 existing lines in 4 files now uncovered.

77857 of 84189 relevant lines covered (92.48%)

435065.83 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)
402,537,948✔
147
{
148
   switch (value.kind) {
402,537,948✔
149
   case JIT_VALUE_REG:
301,213,060✔
150
      JIT_ASSERT(value.reg < state->func->nregs);
301,213,060✔
151
      return state->regs[value.reg].integer;
301,213,060✔
152
   case JIT_VALUE_INT64:
101,324,888✔
153
   case JIT_VALUE_DOUBLE:
154
   case JIT_ADDR_ABS:
155
      return value.int64;
101,324,888✔
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)
2,765,049✔
163
{
164
   switch (value.kind) {
2,765,049✔
165
   case JIT_VALUE_REG:
2,058,789✔
166
      JIT_ASSERT(value.reg < state->func->nregs);
2,058,789✔
167
      return state->regs[value.reg].real;
2,058,789✔
168
   case JIT_VALUE_INT64:
706,260✔
169
   case JIT_VALUE_DOUBLE:
170
      return value.dval;
706,260✔
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)
123,555,671✔
178
{
179
   switch (value.kind) {
123,555,671✔
180
   case JIT_VALUE_REG:
24,034,815✔
181
      JIT_ASSERT(value.reg < state->func->nregs);
24,034,815✔
182
      return state->regs[value.reg].pointer;
24,034,815✔
183
   case JIT_ADDR_CPOOL:
373,598✔
184
      JIT_ASSERT(value.int64 >= 0 && value.int64 <= state->func->cpoolsz);
373,598✔
185
      return state->func->cpool + value.int64;
373,598✔
186
   case JIT_ADDR_REG:
99,147,258✔
187
      JIT_ASSERT(value.reg < state->func->nregs);
99,147,258✔
188
      return state->regs[value.reg].pointer + value.disp;
99,147,258✔
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,
188,738,935✔
198
                                             jit_value_t value)
199
{
200
   switch (value.kind) {
188,738,935✔
201
   case JIT_VALUE_REG:
156,082,137✔
202
      JIT_ASSERT(value.reg < state->func->nregs);
156,082,137✔
203
      return state->regs[value.reg];
156,082,137✔
204
   case JIT_VALUE_INT64:
31,393,167✔
205
      return (jit_scalar_t){ .integer = value.int64 };
31,393,167✔
206
   case JIT_VALUE_DOUBLE:
249,403✔
207
      return (jit_scalar_t){ .real = value.dval };
249,403✔
208
   case JIT_VALUE_LABEL:
×
209
      return (jit_scalar_t){ .integer = value.label };
×
210
   case JIT_VALUE_HANDLE:
8,858✔
211
      return (jit_scalar_t){ .integer = value.handle };
8,858✔
212
   case JIT_VALUE_LOCUS:
59,220✔
213
      return (jit_scalar_t){ .pointer = value.locus };
59,220✔
214
   case JIT_ADDR_CPOOL:
6,172✔
215
      JIT_ASSERT(value.int64 >= 0 && value.int64 <= state->func->cpoolsz);
6,172✔
216
      return (jit_scalar_t){ .pointer = state->func->cpool + value.int64 };
6,172✔
217
   case JIT_ADDR_REG:
333,787✔
218
      JIT_ASSERT(value.reg < state->func->nregs);
333,787✔
219
      return (jit_scalar_t){
333,787✔
220
         .pointer = state->regs[value.reg].pointer + value.disp
333,787✔
221
      };
222
   case JIT_ADDR_ABS:
606,191✔
223
      return (jit_scalar_t){ .pointer = (void *)(intptr_t)value.int64 };
606,191✔
224
   default:
×
225
      CANNOT_HANDLE(value);
×
226
   }
227
}
228

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

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

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

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

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

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

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

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

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

270
   state->regs[ir->result].integer = arg1 ^ arg2;
11,491,268✔
271
}
11,491,268✔
272

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

278
   if (ir->cc == JIT_CC_O) {
2,740,862✔
279
      int overflow = 0;
6,503✔
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);
6,503✔
288

289
      state->flags = overflow;
6,503✔
290
   }
291
   else if (ir->cc == JIT_CC_C) {
2,734,359✔
292
      int overflow = 0;
430,730✔
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);
430,730✔
301

302
      state->flags = overflow;
430,730✔
303
   }
304
   else
305
      state->regs[ir->result].integer = arg1 * arg2;
2,303,629✔
306
}
2,740,862✔
307

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

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

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

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

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

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

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

337
   if (ir->cc == JIT_CC_O) {
23,683,219✔
338
      int overflow = 0;
514,834✔
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);
514,834✔
347

348
      state->flags = overflow;
514,834✔
349
   }
350
   else if (ir->cc == JIT_CC_C) {
23,168,385✔
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;
23,168,382✔
365
}
23,683,219✔
366

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

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

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

380
   if (ir->cc == JIT_CC_O) {
57,144,930✔
381
      int overflow = 0;
5,131,820✔
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);
5,131,820✔
390

391
      state->flags = overflow;
5,131,820✔
392
   }
393
   else if (ir->cc == JIT_CC_C) {
52,013,110✔
394
      int overflow = 0;
430,730✔
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);
430,730✔
403

404
      state->flags = overflow;
430,730✔
405
   }
406
   else
407
      state->regs[ir->result].integer = arg1 + arg2;
51,582,380✔
408
}
57,144,930✔
409

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

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

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

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

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

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

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

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

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

450
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
31,871,559✔
451
   JIT_ASSERT(arg2 != NULL);
31,871,559✔
452
   JIT_ASSERT((intptr_t)arg2 >= 4096);
31,871,559✔
453

454
   switch (ir->size) {
31,871,559✔
455
   case JIT_SZ_8:
9,050,757✔
456
      unaligned_store(arg2, arg1.integer, uint8_t);
9,050,757✔
457
      break;
9,050,757✔
458
   case JIT_SZ_16:
1,545✔
459
      unaligned_store(arg2, arg1.integer, uint16_t);
1,545✔
460
      break;
1,545✔
461
   case JIT_SZ_32:
13,974,759✔
462
      unaligned_store(arg2, arg1.integer, uint32_t);
13,974,759✔
463
      break;
13,974,759✔
464
   case JIT_SZ_64:
8,844,498✔
465
      unaligned_store(arg2, arg1.integer, uint64_t);
8,844,498✔
466
      break;
8,844,498✔
467
   case JIT_SZ_UNSPEC:
×
468
      should_not_reach_here();
469
   }
470
}
31,871,559✔
471

472
static void interp_uload(jit_interp_t *state, jit_ir_t *ir)
10,188,081✔
473
{
474
   void *arg1 = interp_get_pointer(state, ir->arg1);
10,188,081✔
475

476
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
10,188,081✔
477
   JIT_ASSERT(arg1 != NULL);
10,188,081✔
478
   JIT_ASSERT((intptr_t)arg1 >= 4096);
10,188,081✔
479

480
   switch (ir->size) {
10,188,081✔
481
   case JIT_SZ_8:
10,188,003✔
482
      state->regs[ir->result].integer = *(uint8_t *)arg1;
10,188,003✔
483
      break;
10,188,003✔
484
   case JIT_SZ_16:
9✔
485
      state->regs[ir->result].integer = *(uint16_t *)arg1;
9✔
486
      break;
9✔
487
   case JIT_SZ_32:
47✔
488
      state->regs[ir->result].integer = *(uint32_t *)arg1;
47✔
489
      break;
47✔
490
   case JIT_SZ_64:
22✔
491
      state->regs[ir->result].integer = *(uint64_t *)arg1;
22✔
492
      break;
22✔
493
   case JIT_SZ_UNSPEC:
494
      break;
495
   }
496
}
10,188,081✔
497

498
static void interp_load(jit_interp_t *state, jit_ir_t *ir)
57,983,963✔
499
{
500
   void *arg1 = interp_get_pointer(state, ir->arg1);
57,983,963✔
501

502
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
57,983,963✔
503
   JIT_ASSERT(arg1 != NULL);
57,983,963✔
504
   JIT_ASSERT((intptr_t)arg1 >= 4096);
57,983,963✔
505

506
   switch (ir->size) {
57,983,963✔
507
   case JIT_SZ_8:
14✔
508
      state->regs[ir->result].integer = *(int8_t *)arg1;
14✔
509
      break;
14✔
510
   case JIT_SZ_16:
×
511
      state->regs[ir->result].integer = *(int16_t *)arg1;
×
512
      break;
×
513
   case JIT_SZ_32:
23,125,826✔
514
      state->regs[ir->result].integer = *(int32_t *)arg1;
23,125,826✔
515
      break;
23,125,826✔
516
   case JIT_SZ_64:
34,858,123✔
517
      state->regs[ir->result].integer = *(int64_t *)arg1;
34,858,123✔
518
      break;
34,858,123✔
519
   case JIT_SZ_UNSPEC:
520
      break;
521
   }
522
}
57,983,963✔
523

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

529
   switch (ir->cc) {
59,236,223✔
530
   case JIT_CC_EQ: state->flags = (arg1 == arg2); break;
21,542,807✔
531
   case JIT_CC_NE: state->flags = (arg1 != arg2); break;
8,289,666✔
532
   case JIT_CC_LT: state->flags = (arg1 < arg2); break;
18,498,552✔
533
   case JIT_CC_GT: state->flags = (arg1 > arg2); break;
3,982,486✔
534
   case JIT_CC_LE: state->flags = (arg1 <= arg2); break;
8,033✔
535
   case JIT_CC_GE: state->flags = (arg1 >= arg2); break;
6,914,679✔
536
   default: state->flags = 0; break;
×
537
   }
538
}
59,236,223✔
539

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

545
   switch (ir->cc) {
7,059,749✔
546
   case JIT_CC_EQ: state->flags &= (arg1 == arg2); break;
220,528✔
547
   case JIT_CC_NE: state->flags &= (arg1 != arg2); break;
×
548
   case JIT_CC_LT: state->flags &= (arg1 < arg2); break;
33,921✔
549
   case JIT_CC_GT: state->flags &= (arg1 > arg2); break;
28,517✔
550
   case JIT_CC_LE: state->flags &= (arg1 <= arg2); break;
6,776,783✔
551
   case JIT_CC_GE: state->flags &= (arg1 >= arg2); break;
×
552
   default: state->flags = 0; break;
×
553
   }
554
}
7,059,749✔
555

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

561
   switch (ir->cc) {
632,771✔
562
   case JIT_CC_EQ: state->flags = (arg1 == arg2); break;
53,543✔
563
   case JIT_CC_NE: state->flags = (arg1 != arg2); break;
22✔
564
   case JIT_CC_LT: state->flags = (arg1 < arg2); break;
113,370✔
565
   case JIT_CC_GT: state->flags = (arg1 > arg2); break;
9,025✔
566
   case JIT_CC_LE: state->flags = (arg1 <= arg2); break;
303✔
567
   case JIT_CC_GE: state->flags = (arg1 >= arg2); break;
456,508✔
568
   default: state->flags = 0; break;
×
569
   }
570
}
632,771✔
571

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

577
   switch (ir->cc) {
108,794✔
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;
108,794✔
583
   case JIT_CC_GE: state->flags &= (arg1 >= arg2); break;
×
584
   default: state->flags = 0; break;
×
585
   }
586
}
108,794✔
587

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

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

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

600
   state->regs[ir->result].integer = value < 0 ? 0 : value;
5,508,501✔
601
}
5,508,501✔
602

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

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

615
static void interp_jump(jit_interp_t *state, jit_ir_t *ir)
56,403,599✔
616
{
617
   switch (ir->cc) {
56,403,599✔
618
   case JIT_CC_NONE:
14,136,614✔
619
      interp_branch_to(state, ir->arg1);
14,136,614✔
620
      break;
14,136,614✔
621
   case JIT_CC_T:
28,640,065✔
622
      if (state->flags)
28,640,065✔
623
         interp_branch_to(state, ir->arg1);
14,883,077✔
624
      break;
625
   case JIT_CC_F:
13,626,920✔
626
      if (!state->flags)
13,626,920✔
627
         interp_branch_to(state, ir->arg1);
13,172,661✔
628
      break;
629
   default:
×
630
      interp_dump(state);
×
631
      fatal_trace("unhandled jump condition code");
632
   }
633
}
56,403,599✔
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)
8,220,168✔
642
{
643
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_HANDLE);
8,220,168✔
644

645
   state->anchor->irpos = ir - state->func->irbuf;
8,220,168✔
646

647
   if (ir->arg1.handle == JIT_HANDLE_INVALID) {
8,220,168✔
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);
8,220,168✔
653
      jit_entry_fn_t entry = load_acquire(&f->entry);
8,220,168✔
654
      (*entry)(f, state->anchor, state->args, state->tlab);
8,220,168✔
655
   }
656
}
8,219,559✔
657

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

663
static void interp_csel(jit_interp_t *state, jit_ir_t *ir)
27,085,337✔
664
{
665
   if (state->flags)
27,085,337✔
666
      state->regs[ir->result].integer = interp_get_int(state, ir->arg1);
33,027,790✔
667
   else
668
      state->regs[ir->result].integer = interp_get_int(state, ir->arg2);
21,142,884✔
669
}
27,085,337✔
670

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

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

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

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

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

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

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

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

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

715
   if (ir->cc == JIT_CC_O) {
130✔
716
      int overflow = 0, xo = 0;
119✔
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);
450✔
730

731
      state->flags = overflow;
119✔
732
   }
733
   else if (ir->cc == JIT_CC_C) {
11✔
734
      int overflow = 0, xo = 0;
10✔
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);
49✔
748

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

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

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

765
   memcpy(dest, src, count);
331,036✔
766
}
331,036✔
767

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

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

777
   memmove(dest, src, count);
3,056,557✔
778
}
3,056,557✔
779

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

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

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

794
   JIT_ASSERT(dest != NULL);
413,455✔
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);
152,422,074✔
804
}
413,455✔
805

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

811
   state->anchor->irpos = ir - state->func->irbuf;
236,026✔
812

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

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

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

824
   thread->anchor = NULL;
236,021✔
825
}
236,021✔
826

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

832
   state->anchor->irpos = ir - state->func->irbuf;
2,100,267✔
833

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

837
   thread->anchor = NULL;
2,100,267✔
838
}
2,100,267✔
839

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

846
static void interp_exit(jit_interp_t *state, jit_ir_t *ir)
2,836,687✔
847
{
848
   state->anchor->irpos = ir - state->func->irbuf;
2,836,687✔
849
   __nvc_do_exit(ir->arg1.exit, state->anchor, state->args, state->tlab);
2,836,687✔
850
}
2,836,021✔
851

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

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

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

873
   if (test.integer == cmp)
382,664✔
874
      interp_branch_to(state, ir->arg2);
183,830✔
875
}
382,664✔
876

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

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

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

894
   JIT_ASSERT(ptr != NULL);
2,635✔
895
   JIT_ASSERT((intptr_t)ptr >= 4096);
2,635✔
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);
2,635✔
903
}
2,635✔
904

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

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

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

925
static void interp_loop(jit_interp_t *state)
4,155,302✔
926
{
927
   for (;;) {
963,978,527✔
928
      JIT_ASSERT(state->pc < state->func->nirs);
963,978,527✔
929
      jit_ir_t *ir = &(state->func->irbuf[state->pc++]);
963,978,527✔
930
      switch (ir->op) {
963,978,527✔
931
      case J_RECV:
25,103,620✔
932
         interp_recv(state, ir);
25,103,620✔
933
         break;
25,103,620✔
934
      case J_SEND:
51,940,293✔
935
         interp_send(state, ir);
51,940,293✔
936
         break;
51,940,293✔
937
      case J_AND:
1,081,480✔
938
         interp_and(state, ir);
1,081,480✔
939
         break;
1,081,480✔
940
      case J_OR:
2,061,021✔
941
         interp_or(state, ir);
2,061,021✔
942
         break;
2,061,021✔
943
      case J_XOR:
11,491,268✔
944
         interp_xor(state, ir);
11,491,268✔
945
         break;
11,491,268✔
946
      case J_SUB:
23,683,219✔
947
         interp_sub(state, ir);
23,683,219✔
948
         break;
23,683,219✔
949
      case J_FSUB:
75,034✔
950
         interp_fsub(state, ir);
75,034✔
951
         break;
75,034✔
952
      case J_ADD:
57,144,930✔
953
         interp_add(state, ir);
57,144,930✔
954
         break;
57,144,930✔
955
      case J_FADD:
73,365✔
956
         interp_fadd(state, ir);
73,365✔
957
         break;
73,365✔
958
      case J_MUL:
2,740,862✔
959
         interp_mul(state, ir);
2,740,862✔
960
         break;
2,740,862✔
961
      case J_FMUL:
99,266✔
962
         interp_fmul(state, ir);
99,266✔
963
         break;
99,266✔
964
      case J_DIV:
708,145✔
965
         interp_div(state, ir);
708,145✔
966
         break;
708,145✔
967
      case J_FDIV:
14,231✔
968
         interp_fdiv(state, ir);
14,231✔
969
         break;
14,231✔
970
      case J_SHL:
6,803,135✔
971
         interp_shl(state, ir);
6,803,135✔
972
         break;
6,803,135✔
973
      case J_SHR:
722✔
974
         interp_shr(state, ir);
722✔
975
         break;
722✔
976
      case J_ASR:
8,989,294✔
977
         interp_asr(state, ir);
8,989,294✔
978
         break;
8,989,294✔
979
      case J_RET:
980
         return;
981
      case J_STORE:
31,871,559✔
982
         interp_store(state, ir);
31,871,559✔
983
         break;
31,871,559✔
984
      case J_ULOAD:
10,188,081✔
985
         interp_uload(state, ir);
10,188,081✔
986
         break;
10,188,081✔
987
      case J_LOAD:
57,983,963✔
988
         interp_load(state, ir);
57,983,963✔
989
         break;
57,983,963✔
990
      case J_CMP:
59,236,223✔
991
         interp_cmp(state, ir);
59,236,223✔
992
         break;
59,236,223✔
993
      case J_CCMP:
7,059,749✔
994
         interp_ccmp(state, ir);
7,059,749✔
995
         break;
7,059,749✔
996
      case J_FCMP:
632,771✔
997
         interp_fcmp(state, ir);
632,771✔
998
         break;
632,771✔
999
      case J_FCCMP:
108,794✔
1000
         interp_fccmp(state, ir);
108,794✔
1001
         break;
108,794✔
1002
      case J_CSET:
26,196,207✔
1003
         interp_cset(state, ir);
26,196,207✔
1004
         break;
26,196,207✔
1005
      case J_JUMP:
56,403,599✔
1006
         interp_jump(state, ir);
56,403,599✔
1007
         break;
56,403,599✔
1008
      case J_TRAP:
×
1009
         interp_trap(state, ir);
×
1010
         break;
1011
      case J_CALL:
8,220,168✔
1012
         interp_call(state, ir);
8,220,168✔
1013
         break;
8,220,168✔
1014
      case J_MOV:
104,756,793✔
1015
         interp_mov(state, ir);
104,756,793✔
1016
         break;
104,756,793✔
1017
      case J_CSEL:
27,085,337✔
1018
         interp_csel(state, ir);
27,085,337✔
1019
         break;
27,085,337✔
1020
      case J_NEG:
1,780,396✔
1021
         interp_neg(state, ir);
1,780,396✔
1022
         break;
1,780,396✔
1023
      case J_FNEG:
53,984✔
1024
         interp_fneg(state, ir);
53,984✔
1025
         break;
53,984✔
1026
      case J_NOT:
717,526✔
1027
         interp_not(state, ir);
717,526✔
1028
         break;
717,526✔
1029
      case J_SCVTF:
358,914✔
1030
         interp_scvtf(state, ir);
358,914✔
1031
         break;
358,914✔
1032
      case J_FCVTNS:
7,099✔
1033
         interp_fcvtns(state, ir);
7,099✔
1034
         break;
7,099✔
1035
      case J_LEA:
14,494,392✔
1036
         interp_lea(state, ir);
14,494,392✔
1037
         break;
14,494,392✔
1038
      case J_REM:
793,997✔
1039
         interp_rem(state, ir);
793,997✔
1040
         break;
793,997✔
1041
      case J_CLAMP:
5,508,501✔
1042
         interp_clamp(state, ir);
5,508,501✔
1043
         break;
5,508,501✔
1044
      case J_DEBUG:
1045
      case J_NOP:
1046
         break;
1047
      case MACRO_COPY:
331,036✔
1048
         interp_copy(state, ir);
331,036✔
1049
         break;
331,036✔
1050
      case MACRO_MOVE:
3,056,557✔
1051
         interp_move(state, ir);
3,056,557✔
1052
         break;
3,056,557✔
1053
      case MACRO_BZERO:
1,452,804✔
1054
         interp_bzero(state, ir);
1,452,804✔
1055
         break;
1,452,804✔
1056
      case MACRO_MEMSET:
413,455✔
1057
         interp_memset(state, ir);
413,455✔
1058
         break;
413,455✔
1059
      case MACRO_GALLOC:
236,026✔
1060
         interp_galloc(state, ir);
236,026✔
1061
         break;
236,026✔
1062
      case MACRO_LALLOC:
2,100,267✔
1063
         interp_lalloc(state, ir);
2,100,267✔
1064
         break;
2,100,267✔
1065
      case MACRO_SALLOC:
6,274,306✔
1066
         interp_salloc(state, ir);
6,274,306✔
1067
         break;
6,274,306✔
1068
      case MACRO_EXIT:
2,836,687✔
1069
         interp_exit(state, ir);
2,836,687✔
1070
         break;
2,836,687✔
1071
      case MACRO_FEXP:
348,522✔
1072
         interp_fexp(state, ir);
348,522✔
1073
         break;
348,522✔
1074
      case MACRO_EXP:
130✔
1075
         interp_exp(state, ir);
130✔
1076
         break;
130✔
1077
      case MACRO_GETPRIV:
2,780,412✔
1078
         interp_getpriv(state, ir);
2,780,412✔
1079
         break;
2,780,412✔
1080
      case MACRO_PUTPRIV:
9,719✔
1081
         interp_putpriv(state, ir);
9,719✔
1082
         break;
9,719✔
1083
      case MACRO_CASE:
382,664✔
1084
         interp_case(state, ir);
382,664✔
1085
         break;
382,664✔
1086
      case MACRO_TRIM:
500,780✔
1087
         interp_trim(state, ir);
500,780✔
1088
         break;
500,780✔
1089
      case MACRO_REEXEC:
1,037✔
1090
         interp_reexec(state, ir);
1,037✔
1091
         return;
1,037✔
1092
      case MACRO_SADD:
2,635✔
1093
         interp_sadd(state, ir);
2,635✔
1094
         break;
2,635✔
1095
      case MACRO_PACK:
363,877✔
1096
         interp_pack(state, ir);
363,877✔
1097
         break;
363,877✔
1098
      case MACRO_UNPACK:
85,145✔
1099
         interp_unpack(state, ir);
85,145✔
1100
         break;
85,145✔
1101
      case MACRO_VEC4OP:
2,500✔
1102
         interp_vec4op(state, ir);
2,500✔
1103
         break;
2,500✔
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,155,306✔
1112
                tlab_t *tlab)
1113
{
4,155,306✔
1114
   jit_entry_fn_t entry = load_acquire(&f->entry);
4,155,306✔
1115
   if (unlikely(entry != jit_interp)) {
4,155,306✔
1116
      // Raced with a code generation thread installing a compiled
1117
      // version of this function
UNCOV
1118
      return (*entry)(f, caller, args, tlab);
×
1119
   }
1120

1121
   jit_fill_irbuf(f);
4,155,306✔
1122

1123
   if (f->next_tier && --(f->hotness) <= 0)
4,155,302✔
1124
      jit_tier_up(f);
14,419✔
1125

1126
   jit_anchor_t anchor = {
4,155,302✔
1127
      .caller    = caller,
1128
      .func      = f,
1129
      .watermark = tlab->alloc,
4,155,302✔
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,155,302✔
1135
   unsigned char frame[f->framesz + 1];
4,155,302✔
1136

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

1142
   jit_interp_t state = {
4,155,302✔
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,155,302✔
1150
      .anchor   = &anchor,
1151
      .tlab     = tlab,
1152
   };
1153

1154
   interp_loop(&state);
4,155,302✔
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