Coverage Report

Created: 2026-11-12 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm3/source/m3_exec.h
Line
Count
Source
1
//
2
//  m3_exec.h
3
//
4
//  Created by Steven Massey on 4/17/19.
5
//  Copyright © 2019 Steven Massey. All rights reserved.
6
7
8
#ifndef m3_exec_h
9
#define m3_exec_h
10
11
// All these functions could move over to the .c at some point. normally, I'd say screw it,
12
// but it might prove useful to be able to compile m3_exec alone w/ optimizations while the remaining
13
// code is at debug O0
14
15
16
// About the naming convention of these operations/macros (_rs, _sr_, _ss, _srs, etc.)
17
//------------------------------------------------------------------------------------------------------
18
//   - 'r' means register and 's' means slot
19
//   - the first letter is the top of the stack
20
//
21
//  so, for example, _rs means the first operand (the first thing pushed to the stack) is in a slot
22
//  and the second operand (the top of the stack) is in a register
23
//------------------------------------------------------------------------------------------------------
24
25
#ifndef M3_COMPILE_OPCODES
26
#  error "Opcodes should only be included in one compilation unit"
27
#endif
28
29
#include "m3_math_utils.h"
30
#include "m3_compile.h"
31
#include "m3_env.h"
32
#include "m3_info.h"
33
#include "m3_exec_defs.h"
34
#include "m3_atomic.h"
35
#include "m3_host.h"
36
37
#include <limits.h>
38
39
d_m3BeginExternC
40
41
15.0k
#define rewrite_op(OP)             * ((void **) (_pc-1)) = (void*)(OP)
42
43
2.10G
#define immediate(TYPE)            * ((TYPE *) _pc++)
44
0
#define skip_immediate(TYPE)       (_pc++)
45
46
630M
#define slot(TYPE)                 * (TYPE *) (_sp + immediate (i32))
47
194M
#define slot_ptr(TYPE)             (TYPE *) (_sp + immediate (i32))
48
49
// Reads one address, index or length operand from a slot, at the width the
50
// memory or table it belongs to is addressed by. Either way exactly one slot
51
// immediate is consumed; only how much of the slot is read differs.
52
266k
#define d_m3WideOperand(IS64)      ((IS64) ? slot (u64) : (u64) slot (u32))
53
54
// Whether a range fits a memory, written so that it holds for operands of any
55
// magnitude: the subtraction cannot wrap once the start is known to be within
56
// the memory, where start + length could.
57
#define d_m3MemRangeOk(START, LENGTH, MEM)  \
58
   ((START) <= (MEM)->length and (LENGTH) <= (MEM)->length - (START))
59
60
61
#if d_m3EnableOpProfiling
62
d_m3RetSig profileOp (d_m3OpSig, cstr_t i_operationName);
63
#  define nextOp()                 M3_MUSTTAIL return profileOp (d_m3OpAllArgs, __FUNCTION__)
64
#elif d_m3EnableOpTracing
65
d_m3RetSig debugOp (d_m3OpSig, cstr_t i_operationName);
66
#  define nextOp()                 M3_MUSTTAIL return debugOp (d_m3OpAllArgs, __FUNCTION__)
67
#else
68
1.00G
#  define nextOp()                 nextOpDirect()
69
#endif
70
71
// Next-operation preloading. The dispatch load and the indirect jump that consumes it
72
// sit next to each other, so the jump cannot resolve until the load returns. An
73
// operation's _pc is final as soon as it has taken its immediates -- the offsets are
74
// compile-time constants -- so the load can be issued there instead, leaving the
75
// operation's own work as cover for its latency.
76
//
77
// Preloading is dropped in profiling and tracing builds, where dispatch goes through a
78
// hook instead and the loaded pointer would be the wrong thing to call.
79
#if d_m3PreloadNextOp && !(d_m3EnableOpProfiling || d_m3EnableOpTracing)
80
#  define d_m3PreloadNext()        const IM3Operation _nextOp = (IM3Operation) (* _pc)
81
#  define nextOpPreloaded()        M3_MUSTTAIL return _nextOp (_pc + 1, d_m3OpArgs)
82
#else
83
#  define d_m3PreloadNext()
84
329M
#  define nextOpPreloaded()        nextOp()
85
#endif
86
87
#if d_m3EnableOpProfiling
88
d_m3RetSig profileJumpOp (d_m3OpSig, cstr_t i_operationName);
89
// An operation that leaves by a branch never reaches nextOp, so without this it is
90
// absent from the profile entirely and its outgoing edges are attributed to whatever
91
// ran before it. Has to stay one statement: jumpOp appears in brace-less else arms.
92
#  define jumpOp(PC)               M3_MUSTTAIL return profileJumpOp ((pc_t)(PC), d_m3OpArgs, __FUNCTION__)
93
#else
94
47.2M
#  define jumpOp(PC)               jumpOpDirect(PC)
95
#endif
96
97
#if d_m3RecordBacktraces
98
#  define pushBacktraceFrame()            (PushBacktraceFrame (_mem->runtime, _pc - 1))
99
#  define fillBacktraceFrame(FUNCTION)    (FillBacktraceFunctionInfo (_mem->runtime, function))
100
101
#  define newTrap(err)                    return (pushBacktraceFrame (), err)
102
#  define forwardTrap(err)                return err
103
#else
104
132k
#  define pushBacktraceFrame()            do {} while (0)
105
#  define fillBacktraceFrame(FUNCTION)    do {} while (0)
106
107
24.4k
#  define newTrap(err)                    return err
108
8.00M
#  define forwardTrap(err)                return err
109
#endif
110
111
// Trap before an operation that claims a native frame of its own would drive
112
// the native C stack past runtime->stackLimit. Reads the current stack pointer
113
// via a frame-address probe and compares against the low-water mark set by
114
// d_m3StackLimitEnter. Every op that keeps a frame across an inner dispatch
115
// probes here first -- op_Call and op_CallIndirect, and also op_Loop and
116
// op_TryTable, whose frames outlive the body they run. Guarding the frame
117
// claim rather than the call is what keeps op_ReturnCall bounded: the tail
118
// call itself adds nothing, but the frames it leaves standing behind it do.
119
#if d_m3MaxNativeStack > 0
120
#  define d_m3CheckNativeStack()                                               \
121
8.85M
       do {                                                                    \
122
8.85M
           void * _m3Limit = m3MemRuntime (_mem)->stackLimit;                  \
123
8.85M
           if (M3_UNLIKELY (_m3Limit && m3_NativeStackPtr () < _m3Limit))      \
124
8.85M
               newTrap (m3Err_trapStackOverflow);                              \
125
8.85M
       } while (0)
126
#else
127
#  define d_m3CheckNativeStack()           do {} while (0)
128
#endif
129
130
131
#if d_m3HasStackSwitching
132
133
// Calling into compiled code with an explicit register pair, which the replay
134
// needs and the d_m3OpDefaultArgs spelling cannot express.
135
#  if d_m3HasFloat
136
0
#    define d_m3ExpRegArgs(R0, FP0)        (R0), (FP0)
137
#  else
138
#    define d_m3ExpRegArgs(R0, FP0)        (R0)
139
#  endif
140
141
#  if (d_m3EnableOpProfiling || d_m3EnableOpTracing)
142
#    define d_m3CallWithRegs(PC, SP, MEM, R0, FP0)                             \
143
         Call ((PC), (SP), (MEM), d_m3ExpRegArgs (R0, FP0), d_m3BaseCstr)
144
#  else
145
#    define d_m3CallWithRegs(PC, SP, MEM, R0, FP0)                             \
146
0
         Call ((PC), (SP), (MEM), d_m3ExpRegArgs (R0, FP0))
147
#  endif
148
149
// A suspend is on its way up the native stack and this call was holding a
150
// frame: record what it takes to stand that frame back up, then keep unwinding
151
// with whatever the recording says. The registers go in because op_Call
152
// resumes the caller with the ones its own frame was holding.
153
//
154
// Out of line, and deliberately so: op_Call and its two siblings are the
155
// deepest-recursing functions in the interpreter, and a whole M3Frame of
156
// locals on every call is stack the recursion cannot spare - least of all in a
157
// sanitizer build, where each local carries a redzone.
158
//
159
// Called ahead of pushBacktraceFrame: a suspend is not a trap and has no
160
// business writing a backtrace.
161
static M3_NOINLINE
162
m3ret_t RecordCallFrame (IM3Runtime i_runtime, pc_t i_pc, m3stack_t i_sp, IM3Memory i_memory,
163
                         IM3Function i_function, m3reg_t i_r0
164
#  if d_m3HasFloat
165
                         ,
166
                         f64 i_fp0
167
#  endif
168
)
169
0
{
170
0
    M3Frame frame;
171
172
0
    frame.kind = frame_call;
173
0
    frame.pc = i_pc;
174
0
    frame.sp = i_sp;
175
0
    frame.memory = i_memory;
176
0
    frame.call.function = i_function;
177
0
    frame.call.r0 = i_r0;
178
0
#  if d_m3HasFloat
179
0
    frame.call.fp0 = i_fp0;
180
0
#  endif
181
182
0
    return Continuation_RecordFrame(i_runtime, &frame);
183
0
}
184
185
#  define d_m3RecordCallFrame(MEMORY, FUNCTION)                                \
186
132k
       if (M3_UNLIKELY (r == m3Err_continuationSuspended)) {                   \
187
0
           return RecordCallFrame (m3MemRuntime (_mem), _pc, _sp, (MEMORY),    \
188
0
                                   (FUNCTION), d_m3ExpRegArgs (_r0, _fp0));    \
189
0
       }
190
191
192
// op_Loop and op_TryTable hold native frames across their bodies and nest as
193
// deeply as the Wasm does, so they keep their frames out of this too.
194
static M3_NOINLINE
195
m3ret_t RecordLoopFrame (IM3Runtime i_runtime, pc_t i_pc, m3stack_t i_sp, IM3Memory i_memory)
196
0
{
197
0
    M3Frame frame;
198
199
0
    frame.kind = frame_loop;
200
0
    frame.pc = i_pc;
201
0
    frame.sp = i_sp;
202
0
    frame.memory = i_memory;
203
204
0
    return Continuation_RecordFrame(i_runtime, &frame);
205
0
}
206
207
208
#  if d_m3HasExceptionHandling
209
static M3_NOINLINE
210
m3ret_t RecordTryFrame (IM3Runtime i_runtime, pc_t i_clauses, m3stack_t i_sp, IM3Memory i_memory,
211
                        u32 i_numClauses, bool i_handlersLive)
212
0
{
213
0
    M3Frame frame;
214
215
0
    frame.kind = frame_try;
216
0
    frame.pc = i_clauses;
217
0
    frame.sp = i_sp;
218
0
    frame.memory = i_memory;
219
0
    frame.try_.numClauses = i_numClauses;
220
0
    frame.try_.handlersLive = i_handlersLive;
221
222
0
    return Continuation_RecordFrame(i_runtime, &frame);
223
0
}
224
#  endif
225
226
227
#  if d_m3EntryKeepsFrame
228
static M3_NOINLINE
229
m3ret_t RecordEntryFrame (IM3Runtime i_runtime, pc_t i_pc, m3stack_t i_sp, IM3Memory i_memory,
230
                          IM3Function i_function)
231
{
232
    M3Frame frame;
233
234
    frame.kind = frame_entry;
235
    frame.pc = i_pc;
236
    frame.sp = i_sp;
237
    frame.memory = i_memory;
238
    frame.entry.function = i_function;
239
240
    return Continuation_RecordFrame(i_runtime, &frame);
241
}
242
#  endif
243
#else
244
#  define d_m3RecordCallFrame(MEMORY, FUNCTION)
245
#endif
246
247
248
#if d_m3EnableStrace == 1
249
// Flat trace
250
#  define d_m3TracePrepare
251
#  define d_m3TracePrint(fmt, ...)            fprintf(stderr, fmt "\n", ##__VA_ARGS__)
252
#elif d_m3EnableStrace >= 2
253
// Structured trace
254
#  define d_m3TracePrepare                    const IM3Runtime trace_rt = m3MemRuntime(_mem); (void) trace_rt;
255
#  define d_m3TracePrint(fmt, ...)            fprintf(stderr, "%*s" fmt "\n", (trace_rt->callDepth)*2, "", ##__VA_ARGS__)
256
#else
257
#  define d_m3TracePrepare
258
#  define d_m3TracePrint(fmt, ...)
259
#endif
260
261
#if d_m3EnableStrace >= 3
262
#  define d_m3TraceLoad(TYPE,offset,val)      d_m3TracePrint("load." #TYPE "  0x%x = %" PRI##TYPE, offset, val)
263
#  define d_m3TraceStore(TYPE,offset,val)     d_m3TracePrint("store." #TYPE " 0x%x , %" PRI##TYPE, offset, val)
264
#else
265
#  define d_m3TraceLoad(TYPE,offset,val)
266
#  define d_m3TraceStore(TYPE,offset,val)
267
#endif
268
269
#ifdef DEBUG
270
  #define d_outOfBounds newTrap (ErrorRuntime (m3Err_trapOutOfBoundsMemoryAccess,   \
271
                        _mem->runtime, "memory size: %zu; access offset: %zu",      \
272
                        _mem->length, operand))
273
274
#  define d_outOfBoundsMemOp(OFFSET, SIZE) newTrap (ErrorRuntime (m3Err_trapOutOfBoundsMemoryAccess,   \
275
                     _mem->runtime, "memory size: %zu; access offset: %zu; size: %u",     \
276
                     _mem->length, OFFSET, SIZE))
277
#else
278
100
  #define d_outOfBounds newTrap (m3Err_trapOutOfBoundsMemoryAccess)
279
280
455
#  define d_outOfBoundsMemOp(OFFSET, SIZE) newTrap (m3Err_trapOutOfBoundsMemoryAccess)
281
282
#endif
283
284
#if (d_m3EnableOpProfiling || d_m3EnableOpTracing)
285
d_m3RetSig Call (d_m3OpSig, cstr_t i_operationName)
286
#else
287
d_m3RetSig Call (d_m3OpSig)
288
#endif
289
133k
{
290
133k
    m3ret_t possible_trap = m3_Yield();
291
133k
    if (M3_UNLIKELY(possible_trap)) {
292
0
        return possible_trap;
293
0
    }
294
295
133k
    nextOpDirect();
296
133k
}
297
298
#define d_m3CommutativeOpMacro(RES, REG, TYPE, NAME, OP, ...) \
299
71.1M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
71.1M
{                                                       \
301
71.1M
    TYPE operand = slot (TYPE);                         \
302
71.1M
    d_m3PreloadNext ();                                 \
303
71.1M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
71.1M
    nextOpPreloaded ();                                 \
305
27.3k
}                                                       \
m3_compile.c:op_i32_Equal_rs
Line
Count
Source
299
2.15M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
2.15M
{                                                       \
301
2.15M
    TYPE operand = slot (TYPE);                         \
302
2.15M
    d_m3PreloadNext ();                                 \
303
2.15M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
2.15M
    nextOpPreloaded ();                                 \
305
2.15M
}                                                       \
m3_compile.c:op_i32_NotEqual_rs
Line
Count
Source
299
1.97M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.97M
{                                                       \
301
1.97M
    TYPE operand = slot (TYPE);                         \
302
1.97M
    d_m3PreloadNext ();                                 \
303
1.97M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.97M
    nextOpPreloaded ();                                 \
305
1.97M
}                                                       \
m3_compile.c:op_i32_LessThan_rs
Line
Count
Source
299
1.77M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.77M
{                                                       \
301
1.77M
    TYPE operand = slot (TYPE);                         \
302
1.77M
    d_m3PreloadNext ();                                 \
303
1.77M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.77M
    nextOpPreloaded ();                                 \
305
1.77M
}                                                       \
m3_compile.c:op_u32_LessThan_rs
Line
Count
Source
299
1.63M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.63M
{                                                       \
301
1.63M
    TYPE operand = slot (TYPE);                         \
302
1.63M
    d_m3PreloadNext ();                                 \
303
1.63M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.63M
    nextOpPreloaded ();                                 \
305
1.63M
}                                                       \
m3_compile.c:op_i32_GreaterThan_rs
Line
Count
Source
299
1.48M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.48M
{                                                       \
301
1.48M
    TYPE operand = slot (TYPE);                         \
302
1.48M
    d_m3PreloadNext ();                                 \
303
1.48M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.48M
    nextOpPreloaded ();                                 \
305
1.48M
}                                                       \
m3_compile.c:op_u32_GreaterThan_rs
Line
Count
Source
299
1.63M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.63M
{                                                       \
301
1.63M
    TYPE operand = slot (TYPE);                         \
302
1.63M
    d_m3PreloadNext ();                                 \
303
1.63M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.63M
    nextOpPreloaded ();                                 \
305
1.63M
}                                                       \
m3_compile.c:op_i32_LessThanOrEqual_rs
Line
Count
Source
299
2.13M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
2.13M
{                                                       \
301
2.13M
    TYPE operand = slot (TYPE);                         \
302
2.13M
    d_m3PreloadNext ();                                 \
303
2.13M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
2.13M
    nextOpPreloaded ();                                 \
305
2.13M
}                                                       \
m3_compile.c:op_u32_LessThanOrEqual_rs
Line
Count
Source
299
2.34M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
2.34M
{                                                       \
301
2.34M
    TYPE operand = slot (TYPE);                         \
302
2.34M
    d_m3PreloadNext ();                                 \
303
2.34M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
2.34M
    nextOpPreloaded ();                                 \
305
2.34M
}                                                       \
m3_compile.c:op_i32_GreaterThanOrEqual_rs
Line
Count
Source
299
1.67M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.67M
{                                                       \
301
1.67M
    TYPE operand = slot (TYPE);                         \
302
1.67M
    d_m3PreloadNext ();                                 \
303
1.67M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.67M
    nextOpPreloaded ();                                 \
305
1.67M
}                                                       \
m3_compile.c:op_u32_GreaterThanOrEqual_rs
Line
Count
Source
299
1.75M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.75M
{                                                       \
301
1.75M
    TYPE operand = slot (TYPE);                         \
302
1.75M
    d_m3PreloadNext ();                                 \
303
1.75M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.75M
    nextOpPreloaded ();                                 \
305
1.75M
}                                                       \
m3_compile.c:op_i64_Equal_rs
Line
Count
Source
299
1.35M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.35M
{                                                       \
301
1.35M
    TYPE operand = slot (TYPE);                         \
302
1.35M
    d_m3PreloadNext ();                                 \
303
1.35M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.35M
    nextOpPreloaded ();                                 \
305
1.35M
}                                                       \
m3_compile.c:op_i64_NotEqual_rs
Line
Count
Source
299
1.20M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.20M
{                                                       \
301
1.20M
    TYPE operand = slot (TYPE);                         \
302
1.20M
    d_m3PreloadNext ();                                 \
303
1.20M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.20M
    nextOpPreloaded ();                                 \
305
1.20M
}                                                       \
m3_compile.c:op_i64_LessThan_rs
Line
Count
Source
299
1.53M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.53M
{                                                       \
301
1.53M
    TYPE operand = slot (TYPE);                         \
302
1.53M
    d_m3PreloadNext ();                                 \
303
1.53M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.53M
    nextOpPreloaded ();                                 \
305
1.53M
}                                                       \
m3_compile.c:op_u64_LessThan_rs
Line
Count
Source
299
1.54M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.54M
{                                                       \
301
1.54M
    TYPE operand = slot (TYPE);                         \
302
1.54M
    d_m3PreloadNext ();                                 \
303
1.54M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.54M
    nextOpPreloaded ();                                 \
305
1.54M
}                                                       \
m3_compile.c:op_i64_GreaterThan_rs
Line
Count
Source
299
1.23M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.23M
{                                                       \
301
1.23M
    TYPE operand = slot (TYPE);                         \
302
1.23M
    d_m3PreloadNext ();                                 \
303
1.23M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.23M
    nextOpPreloaded ();                                 \
305
1.23M
}                                                       \
m3_compile.c:op_u64_GreaterThan_rs
Line
Count
Source
299
1.17M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.17M
{                                                       \
301
1.17M
    TYPE operand = slot (TYPE);                         \
302
1.17M
    d_m3PreloadNext ();                                 \
303
1.17M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.17M
    nextOpPreloaded ();                                 \
305
1.17M
}                                                       \
m3_compile.c:op_i64_LessThanOrEqual_rs
Line
Count
Source
299
1.71M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.71M
{                                                       \
301
1.71M
    TYPE operand = slot (TYPE);                         \
302
1.71M
    d_m3PreloadNext ();                                 \
303
1.71M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.71M
    nextOpPreloaded ();                                 \
305
1.71M
}                                                       \
m3_compile.c:op_u64_LessThanOrEqual_rs
Line
Count
Source
299
1.12M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.12M
{                                                       \
301
1.12M
    TYPE operand = slot (TYPE);                         \
302
1.12M
    d_m3PreloadNext ();                                 \
303
1.12M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.12M
    nextOpPreloaded ();                                 \
305
1.12M
}                                                       \
m3_compile.c:op_i64_GreaterThanOrEqual_rs
Line
Count
Source
299
924k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
924k
{                                                       \
301
924k
    TYPE operand = slot (TYPE);                         \
302
924k
    d_m3PreloadNext ();                                 \
303
924k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
924k
    nextOpPreloaded ();                                 \
305
924k
}                                                       \
m3_compile.c:op_u64_GreaterThanOrEqual_rs
Line
Count
Source
299
1.05M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.05M
{                                                       \
301
1.05M
    TYPE operand = slot (TYPE);                         \
302
1.05M
    d_m3PreloadNext ();                                 \
303
1.05M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.05M
    nextOpPreloaded ();                                 \
305
1.05M
}                                                       \
m3_compile.c:op_f32_Equal_rs
Line
Count
Source
299
642k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
642k
{                                                       \
301
642k
    TYPE operand = slot (TYPE);                         \
302
642k
    d_m3PreloadNext ();                                 \
303
642k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
642k
    nextOpPreloaded ();                                 \
305
642k
}                                                       \
m3_compile.c:op_f32_NotEqual_rs
Line
Count
Source
299
830k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
830k
{                                                       \
301
830k
    TYPE operand = slot (TYPE);                         \
302
830k
    d_m3PreloadNext ();                                 \
303
830k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
830k
    nextOpPreloaded ();                                 \
305
830k
}                                                       \
m3_compile.c:op_f32_LessThan_rs
Line
Count
Source
299
367k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
367k
{                                                       \
301
367k
    TYPE operand = slot (TYPE);                         \
302
367k
    d_m3PreloadNext ();                                 \
303
367k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
367k
    nextOpPreloaded ();                                 \
305
367k
}                                                       \
m3_compile.c:op_f32_GreaterThan_rs
Line
Count
Source
299
287k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
287k
{                                                       \
301
287k
    TYPE operand = slot (TYPE);                         \
302
287k
    d_m3PreloadNext ();                                 \
303
287k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
287k
    nextOpPreloaded ();                                 \
305
287k
}                                                       \
m3_compile.c:op_f32_LessThanOrEqual_rs
Line
Count
Source
299
354k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
354k
{                                                       \
301
354k
    TYPE operand = slot (TYPE);                         \
302
354k
    d_m3PreloadNext ();                                 \
303
354k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
354k
    nextOpPreloaded ();                                 \
305
354k
}                                                       \
m3_compile.c:op_f32_GreaterThanOrEqual_rs
Line
Count
Source
299
323k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
323k
{                                                       \
301
323k
    TYPE operand = slot (TYPE);                         \
302
323k
    d_m3PreloadNext ();                                 \
303
323k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
323k
    nextOpPreloaded ();                                 \
305
323k
}                                                       \
m3_compile.c:op_f64_Equal_rs
Line
Count
Source
299
349k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
349k
{                                                       \
301
349k
    TYPE operand = slot (TYPE);                         \
302
349k
    d_m3PreloadNext ();                                 \
303
349k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
349k
    nextOpPreloaded ();                                 \
305
349k
}                                                       \
m3_compile.c:op_f64_NotEqual_rs
Line
Count
Source
299
388k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
388k
{                                                       \
301
388k
    TYPE operand = slot (TYPE);                         \
302
388k
    d_m3PreloadNext ();                                 \
303
388k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
388k
    nextOpPreloaded ();                                 \
305
388k
}                                                       \
m3_compile.c:op_f64_LessThan_rs
Line
Count
Source
299
338k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
338k
{                                                       \
301
338k
    TYPE operand = slot (TYPE);                         \
302
338k
    d_m3PreloadNext ();                                 \
303
338k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
338k
    nextOpPreloaded ();                                 \
305
338k
}                                                       \
m3_compile.c:op_f64_GreaterThan_rs
Line
Count
Source
299
415k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
415k
{                                                       \
301
415k
    TYPE operand = slot (TYPE);                         \
302
415k
    d_m3PreloadNext ();                                 \
303
415k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
415k
    nextOpPreloaded ();                                 \
305
415k
}                                                       \
m3_compile.c:op_f64_LessThanOrEqual_rs
Line
Count
Source
299
281k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
281k
{                                                       \
301
281k
    TYPE operand = slot (TYPE);                         \
302
281k
    d_m3PreloadNext ();                                 \
303
281k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
281k
    nextOpPreloaded ();                                 \
305
281k
}                                                       \
m3_compile.c:op_f64_GreaterThanOrEqual_rs
Line
Count
Source
299
453k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
453k
{                                                       \
301
453k
    TYPE operand = slot (TYPE);                         \
302
453k
    d_m3PreloadNext ();                                 \
303
453k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
453k
    nextOpPreloaded ();                                 \
305
453k
}                                                       \
m3_compile.c:op_i32_Add_rs
Line
Count
Source
299
1.81M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.81M
{                                                       \
301
1.81M
    TYPE operand = slot (TYPE);                         \
302
1.81M
    d_m3PreloadNext ();                                 \
303
1.81M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.81M
    nextOpPreloaded ();                                 \
305
1.81M
}                                                       \
m3_compile.c:op_i32_Subtract_rs
Line
Count
Source
299
1.12M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.12M
{                                                       \
301
1.12M
    TYPE operand = slot (TYPE);                         \
302
1.12M
    d_m3PreloadNext ();                                 \
303
1.12M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.12M
    nextOpPreloaded ();                                 \
305
1.12M
}                                                       \
m3_compile.c:op_i32_Multiply_rs
Line
Count
Source
299
1.42M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.42M
{                                                       \
301
1.42M
    TYPE operand = slot (TYPE);                         \
302
1.42M
    d_m3PreloadNext ();                                 \
303
1.42M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.42M
    nextOpPreloaded ();                                 \
305
1.42M
}                                                       \
m3_compile.c:op_i32_Divide_rs
Line
Count
Source
299
11.1k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
11.1k
{                                                       \
301
11.1k
    TYPE operand = slot (TYPE);                         \
302
11.1k
    d_m3PreloadNext ();                                 \
303
11.1k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
11.1k
    nextOpPreloaded ();                                 \
305
11.1k
}                                                       \
m3_compile.c:op_u32_Divide_rs
Line
Count
Source
299
9.46k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
9.46k
{                                                       \
301
9.46k
    TYPE operand = slot (TYPE);                         \
302
9.46k
    d_m3PreloadNext ();                                 \
303
9.46k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
9.44k
    nextOpPreloaded ();                                 \
305
9.46k
}                                                       \
m3_compile.c:op_i32_Remainder_rs
Line
Count
Source
299
15.8k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
15.8k
{                                                       \
301
15.8k
    TYPE operand = slot (TYPE);                         \
302
15.8k
    d_m3PreloadNext ();                                 \
303
15.8k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
15.7k
    nextOpPreloaded ();                                 \
305
15.8k
}                                                       \
m3_compile.c:op_u32_Remainder_rs
Line
Count
Source
299
9.82k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
9.82k
{                                                       \
301
9.82k
    TYPE operand = slot (TYPE);                         \
302
9.82k
    d_m3PreloadNext ();                                 \
303
9.82k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
9.79k
    nextOpPreloaded ();                                 \
305
9.82k
}                                                       \
m3_compile.c:op_u32_And_rs
Line
Count
Source
299
1.57M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.57M
{                                                       \
301
1.57M
    TYPE operand = slot (TYPE);                         \
302
1.57M
    d_m3PreloadNext ();                                 \
303
1.57M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.57M
    nextOpPreloaded ();                                 \
305
1.57M
}                                                       \
m3_compile.c:op_u32_Or_rs
Line
Count
Source
299
1.59M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.59M
{                                                       \
301
1.59M
    TYPE operand = slot (TYPE);                         \
302
1.59M
    d_m3PreloadNext ();                                 \
303
1.59M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.59M
    nextOpPreloaded ();                                 \
305
1.59M
}                                                       \
m3_compile.c:op_u32_Xor_rs
Line
Count
Source
299
1.78M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.78M
{                                                       \
301
1.78M
    TYPE operand = slot (TYPE);                         \
302
1.78M
    d_m3PreloadNext ();                                 \
303
1.78M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.78M
    nextOpPreloaded ();                                 \
305
1.78M
}                                                       \
m3_compile.c:op_u32_ShiftLeft_rs
Line
Count
Source
299
1.11M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.11M
{                                                       \
301
1.11M
    TYPE operand = slot (TYPE);                         \
302
1.11M
    d_m3PreloadNext ();                                 \
303
1.11M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.11M
    nextOpPreloaded ();                                 \
305
1.11M
}                                                       \
m3_compile.c:op_i32_ShiftRight_rs
Line
Count
Source
299
862k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
862k
{                                                       \
301
862k
    TYPE operand = slot (TYPE);                         \
302
862k
    d_m3PreloadNext ();                                 \
303
862k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
862k
    nextOpPreloaded ();                                 \
305
862k
}                                                       \
m3_compile.c:op_u32_ShiftRight_rs
Line
Count
Source
299
656k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
656k
{                                                       \
301
656k
    TYPE operand = slot (TYPE);                         \
302
656k
    d_m3PreloadNext ();                                 \
303
656k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
656k
    nextOpPreloaded ();                                 \
305
656k
}                                                       \
m3_compile.c:op_u32_Rotl_rs
Line
Count
Source
299
792k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
792k
{                                                       \
301
792k
    TYPE operand = slot (TYPE);                         \
302
792k
    d_m3PreloadNext ();                                 \
303
792k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
792k
    nextOpPreloaded ();                                 \
305
792k
}                                                       \
m3_compile.c:op_u32_Rotr_rs
Line
Count
Source
299
1.15M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.15M
{                                                       \
301
1.15M
    TYPE operand = slot (TYPE);                         \
302
1.15M
    d_m3PreloadNext ();                                 \
303
1.15M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.15M
    nextOpPreloaded ();                                 \
305
1.15M
}                                                       \
m3_compile.c:op_i64_Add_rs
Line
Count
Source
299
1.45M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.45M
{                                                       \
301
1.45M
    TYPE operand = slot (TYPE);                         \
302
1.45M
    d_m3PreloadNext ();                                 \
303
1.45M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.45M
    nextOpPreloaded ();                                 \
305
1.45M
}                                                       \
m3_compile.c:op_i64_Subtract_rs
Line
Count
Source
299
750k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
750k
{                                                       \
301
750k
    TYPE operand = slot (TYPE);                         \
302
750k
    d_m3PreloadNext ();                                 \
303
750k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
750k
    nextOpPreloaded ();                                 \
305
750k
}                                                       \
m3_compile.c:op_i64_Multiply_rs
Line
Count
Source
299
1.78M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.78M
{                                                       \
301
1.78M
    TYPE operand = slot (TYPE);                         \
302
1.78M
    d_m3PreloadNext ();                                 \
303
1.78M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.78M
    nextOpPreloaded ();                                 \
305
1.78M
}                                                       \
m3_compile.c:op_i64_Divide_rs
Line
Count
Source
299
16.2k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
16.2k
{                                                       \
301
16.2k
    TYPE operand = slot (TYPE);                         \
302
16.2k
    d_m3PreloadNext ();                                 \
303
16.2k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
16.2k
    nextOpPreloaded ();                                 \
305
16.2k
}                                                       \
m3_compile.c:op_u64_Divide_rs
Line
Count
Source
299
6.15k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
6.15k
{                                                       \
301
6.15k
    TYPE operand = slot (TYPE);                         \
302
6.15k
    d_m3PreloadNext ();                                 \
303
6.15k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
6.12k
    nextOpPreloaded ();                                 \
305
6.15k
}                                                       \
m3_compile.c:op_i64_Remainder_rs
Line
Count
Source
299
14.2k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
14.2k
{                                                       \
301
14.2k
    TYPE operand = slot (TYPE);                         \
302
14.2k
    d_m3PreloadNext ();                                 \
303
14.2k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
14.2k
    nextOpPreloaded ();                                 \
305
14.2k
}                                                       \
m3_compile.c:op_u64_Remainder_rs
Line
Count
Source
299
13.4k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
13.4k
{                                                       \
301
13.4k
    TYPE operand = slot (TYPE);                         \
302
13.4k
    d_m3PreloadNext ();                                 \
303
13.4k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
13.4k
    nextOpPreloaded ();                                 \
305
13.4k
}                                                       \
m3_compile.c:op_u64_And_rs
Line
Count
Source
299
906k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
906k
{                                                       \
301
906k
    TYPE operand = slot (TYPE);                         \
302
906k
    d_m3PreloadNext ();                                 \
303
906k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
906k
    nextOpPreloaded ();                                 \
305
906k
}                                                       \
m3_compile.c:op_u64_Or_rs
Line
Count
Source
299
1.03M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.03M
{                                                       \
301
1.03M
    TYPE operand = slot (TYPE);                         \
302
1.03M
    d_m3PreloadNext ();                                 \
303
1.03M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.03M
    nextOpPreloaded ();                                 \
305
1.03M
}                                                       \
m3_compile.c:op_u64_Xor_rs
Line
Count
Source
299
1.18M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.18M
{                                                       \
301
1.18M
    TYPE operand = slot (TYPE);                         \
302
1.18M
    d_m3PreloadNext ();                                 \
303
1.18M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.18M
    nextOpPreloaded ();                                 \
305
1.18M
}                                                       \
m3_compile.c:op_u64_ShiftLeft_rs
Line
Count
Source
299
1.05M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.05M
{                                                       \
301
1.05M
    TYPE operand = slot (TYPE);                         \
302
1.05M
    d_m3PreloadNext ();                                 \
303
1.05M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.05M
    nextOpPreloaded ();                                 \
305
1.05M
}                                                       \
m3_compile.c:op_i64_ShiftRight_rs
Line
Count
Source
299
531k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
531k
{                                                       \
301
531k
    TYPE operand = slot (TYPE);                         \
302
531k
    d_m3PreloadNext ();                                 \
303
531k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
531k
    nextOpPreloaded ();                                 \
305
531k
}                                                       \
m3_compile.c:op_u64_ShiftRight_rs
Line
Count
Source
299
897k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
897k
{                                                       \
301
897k
    TYPE operand = slot (TYPE);                         \
302
897k
    d_m3PreloadNext ();                                 \
303
897k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
897k
    nextOpPreloaded ();                                 \
305
897k
}                                                       \
m3_compile.c:op_u64_Rotl_rs
Line
Count
Source
299
856k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
856k
{                                                       \
301
856k
    TYPE operand = slot (TYPE);                         \
302
856k
    d_m3PreloadNext ();                                 \
303
856k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
856k
    nextOpPreloaded ();                                 \
305
856k
}                                                       \
m3_compile.c:op_u64_Rotr_rs
Line
Count
Source
299
802k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
802k
{                                                       \
301
802k
    TYPE operand = slot (TYPE);                         \
302
802k
    d_m3PreloadNext ();                                 \
303
802k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
802k
    nextOpPreloaded ();                                 \
305
802k
}                                                       \
m3_compile.c:op_f32_Add_rs
Line
Count
Source
299
675k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
675k
{                                                       \
301
675k
    TYPE operand = slot (TYPE);                         \
302
675k
    d_m3PreloadNext ();                                 \
303
675k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
675k
    nextOpPreloaded ();                                 \
305
675k
}                                                       \
m3_compile.c:op_f32_Subtract_rs
Line
Count
Source
299
592k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
592k
{                                                       \
301
592k
    TYPE operand = slot (TYPE);                         \
302
592k
    d_m3PreloadNext ();                                 \
303
592k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
592k
    nextOpPreloaded ();                                 \
305
592k
}                                                       \
m3_compile.c:op_f32_Multiply_rs
Line
Count
Source
299
512k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
512k
{                                                       \
301
512k
    TYPE operand = slot (TYPE);                         \
302
512k
    d_m3PreloadNext ();                                 \
303
512k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
512k
    nextOpPreloaded ();                                 \
305
512k
}                                                       \
m3_compile.c:op_f32_Divide_rs
Line
Count
Source
299
4.90k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
4.90k
{                                                       \
301
4.90k
    TYPE operand = slot (TYPE);                         \
302
4.90k
    d_m3PreloadNext ();                                 \
303
4.90k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
4.90k
    nextOpPreloaded ();                                 \
305
4.90k
}                                                       \
m3_compile.c:op_f32_Min_rs
Line
Count
Source
299
1.58M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.58M
{                                                       \
301
1.58M
    TYPE operand = slot (TYPE);                         \
302
1.58M
    d_m3PreloadNext ();                                 \
303
1.58M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.58M
    nextOpPreloaded ();                                 \
305
1.58M
}                                                       \
m3_compile.c:op_f32_Max_rs
Line
Count
Source
299
1.81M
d_m3Op(TYPE##_##NAME##_rs)                              \
300
1.81M
{                                                       \
301
1.81M
    TYPE operand = slot (TYPE);                         \
302
1.81M
    d_m3PreloadNext ();                                 \
303
1.81M
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
1.81M
    nextOpPreloaded ();                                 \
305
1.81M
}                                                       \
m3_compile.c:op_f32_CopySign_rs
Line
Count
Source
299
318k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
318k
{                                                       \
301
318k
    TYPE operand = slot (TYPE);                         \
302
318k
    d_m3PreloadNext ();                                 \
303
318k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
318k
    nextOpPreloaded ();                                 \
305
318k
}                                                       \
m3_compile.c:op_f64_Add_rs
Line
Count
Source
299
577k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
577k
{                                                       \
301
577k
    TYPE operand = slot (TYPE);                         \
302
577k
    d_m3PreloadNext ();                                 \
303
577k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
577k
    nextOpPreloaded ();                                 \
305
577k
}                                                       \
m3_compile.c:op_f64_Subtract_rs
Line
Count
Source
299
553k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
553k
{                                                       \
301
553k
    TYPE operand = slot (TYPE);                         \
302
553k
    d_m3PreloadNext ();                                 \
303
553k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
553k
    nextOpPreloaded ();                                 \
305
553k
}                                                       \
m3_compile.c:op_f64_Multiply_rs
Line
Count
Source
299
662k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
662k
{                                                       \
301
662k
    TYPE operand = slot (TYPE);                         \
302
662k
    d_m3PreloadNext ();                                 \
303
662k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
662k
    nextOpPreloaded ();                                 \
305
662k
}                                                       \
m3_compile.c:op_f64_Divide_rs
Line
Count
Source
299
5.21k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
5.21k
{                                                       \
301
5.21k
    TYPE operand = slot (TYPE);                         \
302
5.21k
    d_m3PreloadNext ();                                 \
303
5.21k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
5.21k
    nextOpPreloaded ();                                 \
305
5.21k
}                                                       \
m3_compile.c:op_f64_Min_rs
Line
Count
Source
299
942k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
942k
{                                                       \
301
942k
    TYPE operand = slot (TYPE);                         \
302
942k
    d_m3PreloadNext ();                                 \
303
942k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
942k
    nextOpPreloaded ();                                 \
305
942k
}                                                       \
m3_compile.c:op_f64_Max_rs
Line
Count
Source
299
932k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
932k
{                                                       \
301
932k
    TYPE operand = slot (TYPE);                         \
302
932k
    d_m3PreloadNext ();                                 \
303
932k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
932k
    nextOpPreloaded ();                                 \
305
932k
}                                                       \
m3_compile.c:op_f64_CopySign_rs
Line
Count
Source
299
176k
d_m3Op(TYPE##_##NAME##_rs)                              \
300
176k
{                                                       \
301
176k
    TYPE operand = slot (TYPE);                         \
302
176k
    d_m3PreloadNext ();                                 \
303
176k
    OP((RES), operand, ((TYPE) REG), ##__VA_ARGS__);    \
304
176k
    nextOpPreloaded ();                                 \
305
176k
}                                                       \
306
101M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
101M
{                                                       \
308
101M
    TYPE operand2 = slot (TYPE);                        \
309
101M
    TYPE operand1 = slot (TYPE);                        \
310
101M
    d_m3PreloadNext ();                                 \
311
101M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
101M
    nextOpPreloaded ();                                 \
313
47.3k
}
m3_compile.c:op_i32_Equal_ss
Line
Count
Source
306
2.19M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.19M
{                                                       \
308
2.19M
    TYPE operand2 = slot (TYPE);                        \
309
2.19M
    TYPE operand1 = slot (TYPE);                        \
310
2.19M
    d_m3PreloadNext ();                                 \
311
2.19M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.19M
    nextOpPreloaded ();                                 \
313
2.19M
}
m3_compile.c:op_i32_NotEqual_ss
Line
Count
Source
306
2.06M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.06M
{                                                       \
308
2.06M
    TYPE operand2 = slot (TYPE);                        \
309
2.06M
    TYPE operand1 = slot (TYPE);                        \
310
2.06M
    d_m3PreloadNext ();                                 \
311
2.06M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.06M
    nextOpPreloaded ();                                 \
313
2.06M
}
m3_compile.c:op_i32_LessThan_ss
Line
Count
Source
306
2.69M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.69M
{                                                       \
308
2.69M
    TYPE operand2 = slot (TYPE);                        \
309
2.69M
    TYPE operand1 = slot (TYPE);                        \
310
2.69M
    d_m3PreloadNext ();                                 \
311
2.69M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.69M
    nextOpPreloaded ();                                 \
313
2.69M
}
m3_compile.c:op_u32_LessThan_ss
Line
Count
Source
306
3.15M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
3.15M
{                                                       \
308
3.15M
    TYPE operand2 = slot (TYPE);                        \
309
3.15M
    TYPE operand1 = slot (TYPE);                        \
310
3.15M
    d_m3PreloadNext ();                                 \
311
3.15M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
3.15M
    nextOpPreloaded ();                                 \
313
3.15M
}
m3_compile.c:op_i32_GreaterThan_ss
Line
Count
Source
306
2.19M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.19M
{                                                       \
308
2.19M
    TYPE operand2 = slot (TYPE);                        \
309
2.19M
    TYPE operand1 = slot (TYPE);                        \
310
2.19M
    d_m3PreloadNext ();                                 \
311
2.19M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.19M
    nextOpPreloaded ();                                 \
313
2.19M
}
m3_compile.c:op_u32_GreaterThan_ss
Line
Count
Source
306
2.14M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.14M
{                                                       \
308
2.14M
    TYPE operand2 = slot (TYPE);                        \
309
2.14M
    TYPE operand1 = slot (TYPE);                        \
310
2.14M
    d_m3PreloadNext ();                                 \
311
2.14M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.14M
    nextOpPreloaded ();                                 \
313
2.14M
}
m3_compile.c:op_i32_LessThanOrEqual_ss
Line
Count
Source
306
3.68M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
3.68M
{                                                       \
308
3.68M
    TYPE operand2 = slot (TYPE);                        \
309
3.68M
    TYPE operand1 = slot (TYPE);                        \
310
3.68M
    d_m3PreloadNext ();                                 \
311
3.68M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
3.68M
    nextOpPreloaded ();                                 \
313
3.68M
}
m3_compile.c:op_u32_LessThanOrEqual_ss
Line
Count
Source
306
2.40M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.40M
{                                                       \
308
2.40M
    TYPE operand2 = slot (TYPE);                        \
309
2.40M
    TYPE operand1 = slot (TYPE);                        \
310
2.40M
    d_m3PreloadNext ();                                 \
311
2.40M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.40M
    nextOpPreloaded ();                                 \
313
2.40M
}
m3_compile.c:op_i32_GreaterThanOrEqual_ss
Line
Count
Source
306
3.33M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
3.33M
{                                                       \
308
3.33M
    TYPE operand2 = slot (TYPE);                        \
309
3.33M
    TYPE operand1 = slot (TYPE);                        \
310
3.33M
    d_m3PreloadNext ();                                 \
311
3.33M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
3.33M
    nextOpPreloaded ();                                 \
313
3.33M
}
m3_compile.c:op_u32_GreaterThanOrEqual_ss
Line
Count
Source
306
1.98M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.98M
{                                                       \
308
1.98M
    TYPE operand2 = slot (TYPE);                        \
309
1.98M
    TYPE operand1 = slot (TYPE);                        \
310
1.98M
    d_m3PreloadNext ();                                 \
311
1.98M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.98M
    nextOpPreloaded ();                                 \
313
1.98M
}
m3_compile.c:op_i64_Equal_ss
Line
Count
Source
306
1.36M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.36M
{                                                       \
308
1.36M
    TYPE operand2 = slot (TYPE);                        \
309
1.36M
    TYPE operand1 = slot (TYPE);                        \
310
1.36M
    d_m3PreloadNext ();                                 \
311
1.36M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.36M
    nextOpPreloaded ();                                 \
313
1.36M
}
m3_compile.c:op_i64_NotEqual_ss
Line
Count
Source
306
2.10M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.10M
{                                                       \
308
2.10M
    TYPE operand2 = slot (TYPE);                        \
309
2.10M
    TYPE operand1 = slot (TYPE);                        \
310
2.10M
    d_m3PreloadNext ();                                 \
311
2.10M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.10M
    nextOpPreloaded ();                                 \
313
2.10M
}
m3_compile.c:op_i64_LessThan_ss
Line
Count
Source
306
1.83M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.83M
{                                                       \
308
1.83M
    TYPE operand2 = slot (TYPE);                        \
309
1.83M
    TYPE operand1 = slot (TYPE);                        \
310
1.83M
    d_m3PreloadNext ();                                 \
311
1.83M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.83M
    nextOpPreloaded ();                                 \
313
1.83M
}
m3_compile.c:op_u64_LessThan_ss
Line
Count
Source
306
2.34M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.34M
{                                                       \
308
2.34M
    TYPE operand2 = slot (TYPE);                        \
309
2.34M
    TYPE operand1 = slot (TYPE);                        \
310
2.34M
    d_m3PreloadNext ();                                 \
311
2.34M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.34M
    nextOpPreloaded ();                                 \
313
2.34M
}
m3_compile.c:op_i64_GreaterThan_ss
Line
Count
Source
306
2.20M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.20M
{                                                       \
308
2.20M
    TYPE operand2 = slot (TYPE);                        \
309
2.20M
    TYPE operand1 = slot (TYPE);                        \
310
2.20M
    d_m3PreloadNext ();                                 \
311
2.20M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.20M
    nextOpPreloaded ();                                 \
313
2.20M
}
m3_compile.c:op_u64_GreaterThan_ss
Line
Count
Source
306
1.70M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.70M
{                                                       \
308
1.70M
    TYPE operand2 = slot (TYPE);                        \
309
1.70M
    TYPE operand1 = slot (TYPE);                        \
310
1.70M
    d_m3PreloadNext ();                                 \
311
1.70M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.70M
    nextOpPreloaded ();                                 \
313
1.70M
}
m3_compile.c:op_i64_LessThanOrEqual_ss
Line
Count
Source
306
1.66M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.66M
{                                                       \
308
1.66M
    TYPE operand2 = slot (TYPE);                        \
309
1.66M
    TYPE operand1 = slot (TYPE);                        \
310
1.66M
    d_m3PreloadNext ();                                 \
311
1.66M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.66M
    nextOpPreloaded ();                                 \
313
1.66M
}
m3_compile.c:op_u64_LessThanOrEqual_ss
Line
Count
Source
306
2.80M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.80M
{                                                       \
308
2.80M
    TYPE operand2 = slot (TYPE);                        \
309
2.80M
    TYPE operand1 = slot (TYPE);                        \
310
2.80M
    d_m3PreloadNext ();                                 \
311
2.80M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.80M
    nextOpPreloaded ();                                 \
313
2.80M
}
m3_compile.c:op_i64_GreaterThanOrEqual_ss
Line
Count
Source
306
1.65M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.65M
{                                                       \
308
1.65M
    TYPE operand2 = slot (TYPE);                        \
309
1.65M
    TYPE operand1 = slot (TYPE);                        \
310
1.65M
    d_m3PreloadNext ();                                 \
311
1.65M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.65M
    nextOpPreloaded ();                                 \
313
1.65M
}
m3_compile.c:op_u64_GreaterThanOrEqual_ss
Line
Count
Source
306
2.46M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.46M
{                                                       \
308
2.46M
    TYPE operand2 = slot (TYPE);                        \
309
2.46M
    TYPE operand1 = slot (TYPE);                        \
310
2.46M
    d_m3PreloadNext ();                                 \
311
2.46M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.46M
    nextOpPreloaded ();                                 \
313
2.46M
}
m3_compile.c:op_f32_Equal_ss
Line
Count
Source
306
590k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
590k
{                                                       \
308
590k
    TYPE operand2 = slot (TYPE);                        \
309
590k
    TYPE operand1 = slot (TYPE);                        \
310
590k
    d_m3PreloadNext ();                                 \
311
590k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
590k
    nextOpPreloaded ();                                 \
313
590k
}
m3_compile.c:op_f32_NotEqual_ss
Line
Count
Source
306
508k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
508k
{                                                       \
308
508k
    TYPE operand2 = slot (TYPE);                        \
309
508k
    TYPE operand1 = slot (TYPE);                        \
310
508k
    d_m3PreloadNext ();                                 \
311
508k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
508k
    nextOpPreloaded ();                                 \
313
508k
}
m3_compile.c:op_f32_LessThan_ss
Line
Count
Source
306
723k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
723k
{                                                       \
308
723k
    TYPE operand2 = slot (TYPE);                        \
309
723k
    TYPE operand1 = slot (TYPE);                        \
310
723k
    d_m3PreloadNext ();                                 \
311
723k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
723k
    nextOpPreloaded ();                                 \
313
723k
}
m3_compile.c:op_f32_GreaterThan_ss
Line
Count
Source
306
601k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
601k
{                                                       \
308
601k
    TYPE operand2 = slot (TYPE);                        \
309
601k
    TYPE operand1 = slot (TYPE);                        \
310
601k
    d_m3PreloadNext ();                                 \
311
601k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
601k
    nextOpPreloaded ();                                 \
313
601k
}
m3_compile.c:op_f32_LessThanOrEqual_ss
Line
Count
Source
306
702k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
702k
{                                                       \
308
702k
    TYPE operand2 = slot (TYPE);                        \
309
702k
    TYPE operand1 = slot (TYPE);                        \
310
702k
    d_m3PreloadNext ();                                 \
311
702k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
702k
    nextOpPreloaded ();                                 \
313
702k
}
m3_compile.c:op_f32_GreaterThanOrEqual_ss
Line
Count
Source
306
573k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
573k
{                                                       \
308
573k
    TYPE operand2 = slot (TYPE);                        \
309
573k
    TYPE operand1 = slot (TYPE);                        \
310
573k
    d_m3PreloadNext ();                                 \
311
573k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
573k
    nextOpPreloaded ();                                 \
313
573k
}
m3_compile.c:op_f64_Equal_ss
Line
Count
Source
306
398k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
398k
{                                                       \
308
398k
    TYPE operand2 = slot (TYPE);                        \
309
398k
    TYPE operand1 = slot (TYPE);                        \
310
398k
    d_m3PreloadNext ();                                 \
311
398k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
398k
    nextOpPreloaded ();                                 \
313
398k
}
m3_compile.c:op_f64_NotEqual_ss
Line
Count
Source
306
535k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
535k
{                                                       \
308
535k
    TYPE operand2 = slot (TYPE);                        \
309
535k
    TYPE operand1 = slot (TYPE);                        \
310
535k
    d_m3PreloadNext ();                                 \
311
535k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
535k
    nextOpPreloaded ();                                 \
313
535k
}
m3_compile.c:op_f64_LessThan_ss
Line
Count
Source
306
361k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
361k
{                                                       \
308
361k
    TYPE operand2 = slot (TYPE);                        \
309
361k
    TYPE operand1 = slot (TYPE);                        \
310
361k
    d_m3PreloadNext ();                                 \
311
361k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
361k
    nextOpPreloaded ();                                 \
313
361k
}
m3_compile.c:op_f64_GreaterThan_ss
Line
Count
Source
306
433k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
433k
{                                                       \
308
433k
    TYPE operand2 = slot (TYPE);                        \
309
433k
    TYPE operand1 = slot (TYPE);                        \
310
433k
    d_m3PreloadNext ();                                 \
311
433k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
433k
    nextOpPreloaded ();                                 \
313
433k
}
m3_compile.c:op_f64_LessThanOrEqual_ss
Line
Count
Source
306
498k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
498k
{                                                       \
308
498k
    TYPE operand2 = slot (TYPE);                        \
309
498k
    TYPE operand1 = slot (TYPE);                        \
310
498k
    d_m3PreloadNext ();                                 \
311
498k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
498k
    nextOpPreloaded ();                                 \
313
498k
}
m3_compile.c:op_f64_GreaterThanOrEqual_ss
Line
Count
Source
306
480k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
480k
{                                                       \
308
480k
    TYPE operand2 = slot (TYPE);                        \
309
480k
    TYPE operand1 = slot (TYPE);                        \
310
480k
    d_m3PreloadNext ();                                 \
311
480k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
480k
    nextOpPreloaded ();                                 \
313
480k
}
m3_compile.c:op_i32_Add_ss
Line
Count
Source
306
1.89M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.89M
{                                                       \
308
1.89M
    TYPE operand2 = slot (TYPE);                        \
309
1.89M
    TYPE operand1 = slot (TYPE);                        \
310
1.89M
    d_m3PreloadNext ();                                 \
311
1.89M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.89M
    nextOpPreloaded ();                                 \
313
1.89M
}
m3_compile.c:op_i32_Subtract_ss
Line
Count
Source
306
1.64M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.64M
{                                                       \
308
1.64M
    TYPE operand2 = slot (TYPE);                        \
309
1.64M
    TYPE operand1 = slot (TYPE);                        \
310
1.64M
    d_m3PreloadNext ();                                 \
311
1.64M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.64M
    nextOpPreloaded ();                                 \
313
1.64M
}
m3_compile.c:op_i32_Multiply_ss
Line
Count
Source
306
2.14M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.14M
{                                                       \
308
2.14M
    TYPE operand2 = slot (TYPE);                        \
309
2.14M
    TYPE operand1 = slot (TYPE);                        \
310
2.14M
    d_m3PreloadNext ();                                 \
311
2.14M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.14M
    nextOpPreloaded ();                                 \
313
2.14M
}
m3_compile.c:op_i32_Divide_ss
Line
Count
Source
306
20.0k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
20.0k
{                                                       \
308
20.0k
    TYPE operand2 = slot (TYPE);                        \
309
20.0k
    TYPE operand1 = slot (TYPE);                        \
310
20.0k
    d_m3PreloadNext ();                                 \
311
20.0k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
20.0k
    nextOpPreloaded ();                                 \
313
20.0k
}
m3_compile.c:op_u32_Divide_ss
Line
Count
Source
306
17.6k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
17.6k
{                                                       \
308
17.6k
    TYPE operand2 = slot (TYPE);                        \
309
17.6k
    TYPE operand1 = slot (TYPE);                        \
310
17.6k
    d_m3PreloadNext ();                                 \
311
17.6k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
17.6k
    nextOpPreloaded ();                                 \
313
17.6k
}
m3_compile.c:op_i32_Remainder_ss
Line
Count
Source
306
20.0k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
20.0k
{                                                       \
308
20.0k
    TYPE operand2 = slot (TYPE);                        \
309
20.0k
    TYPE operand1 = slot (TYPE);                        \
310
20.0k
    d_m3PreloadNext ();                                 \
311
20.0k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
19.9k
    nextOpPreloaded ();                                 \
313
20.0k
}
m3_compile.c:op_u32_Remainder_ss
Line
Count
Source
306
16.7k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
16.7k
{                                                       \
308
16.7k
    TYPE operand2 = slot (TYPE);                        \
309
16.7k
    TYPE operand1 = slot (TYPE);                        \
310
16.7k
    d_m3PreloadNext ();                                 \
311
16.7k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
16.6k
    nextOpPreloaded ();                                 \
313
16.7k
}
m3_compile.c:op_u32_And_ss
Line
Count
Source
306
1.86M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.86M
{                                                       \
308
1.86M
    TYPE operand2 = slot (TYPE);                        \
309
1.86M
    TYPE operand1 = slot (TYPE);                        \
310
1.86M
    d_m3PreloadNext ();                                 \
311
1.86M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.86M
    nextOpPreloaded ();                                 \
313
1.86M
}
m3_compile.c:op_u32_Or_ss
Line
Count
Source
306
1.60M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.60M
{                                                       \
308
1.60M
    TYPE operand2 = slot (TYPE);                        \
309
1.60M
    TYPE operand1 = slot (TYPE);                        \
310
1.60M
    d_m3PreloadNext ();                                 \
311
1.60M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.60M
    nextOpPreloaded ();                                 \
313
1.60M
}
m3_compile.c:op_u32_Xor_ss
Line
Count
Source
306
2.53M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.53M
{                                                       \
308
2.53M
    TYPE operand2 = slot (TYPE);                        \
309
2.53M
    TYPE operand1 = slot (TYPE);                        \
310
2.53M
    d_m3PreloadNext ();                                 \
311
2.53M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.53M
    nextOpPreloaded ();                                 \
313
2.53M
}
m3_compile.c:op_u32_ShiftLeft_ss
Line
Count
Source
306
1.57M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.57M
{                                                       \
308
1.57M
    TYPE operand2 = slot (TYPE);                        \
309
1.57M
    TYPE operand1 = slot (TYPE);                        \
310
1.57M
    d_m3PreloadNext ();                                 \
311
1.57M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.57M
    nextOpPreloaded ();                                 \
313
1.57M
}
m3_compile.c:op_i32_ShiftRight_ss
Line
Count
Source
306
1.19M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.19M
{                                                       \
308
1.19M
    TYPE operand2 = slot (TYPE);                        \
309
1.19M
    TYPE operand1 = slot (TYPE);                        \
310
1.19M
    d_m3PreloadNext ();                                 \
311
1.19M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.19M
    nextOpPreloaded ();                                 \
313
1.19M
}
m3_compile.c:op_u32_ShiftRight_ss
Line
Count
Source
306
1.12M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.12M
{                                                       \
308
1.12M
    TYPE operand2 = slot (TYPE);                        \
309
1.12M
    TYPE operand1 = slot (TYPE);                        \
310
1.12M
    d_m3PreloadNext ();                                 \
311
1.12M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.12M
    nextOpPreloaded ();                                 \
313
1.12M
}
m3_compile.c:op_u32_Rotl_ss
Line
Count
Source
306
1.50M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.50M
{                                                       \
308
1.50M
    TYPE operand2 = slot (TYPE);                        \
309
1.50M
    TYPE operand1 = slot (TYPE);                        \
310
1.50M
    d_m3PreloadNext ();                                 \
311
1.50M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.50M
    nextOpPreloaded ();                                 \
313
1.50M
}
m3_compile.c:op_u32_Rotr_ss
Line
Count
Source
306
2.43M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.43M
{                                                       \
308
2.43M
    TYPE operand2 = slot (TYPE);                        \
309
2.43M
    TYPE operand1 = slot (TYPE);                        \
310
2.43M
    d_m3PreloadNext ();                                 \
311
2.43M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.43M
    nextOpPreloaded ();                                 \
313
2.43M
}
m3_compile.c:op_i64_Add_ss
Line
Count
Source
306
2.37M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.37M
{                                                       \
308
2.37M
    TYPE operand2 = slot (TYPE);                        \
309
2.37M
    TYPE operand1 = slot (TYPE);                        \
310
2.37M
    d_m3PreloadNext ();                                 \
311
2.37M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.37M
    nextOpPreloaded ();                                 \
313
2.37M
}
m3_compile.c:op_i64_Subtract_ss
Line
Count
Source
306
2.02M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.02M
{                                                       \
308
2.02M
    TYPE operand2 = slot (TYPE);                        \
309
2.02M
    TYPE operand1 = slot (TYPE);                        \
310
2.02M
    d_m3PreloadNext ();                                 \
311
2.02M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.02M
    nextOpPreloaded ();                                 \
313
2.02M
}
m3_compile.c:op_i64_Multiply_ss
Line
Count
Source
306
3.48M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
3.48M
{                                                       \
308
3.48M
    TYPE operand2 = slot (TYPE);                        \
309
3.48M
    TYPE operand1 = slot (TYPE);                        \
310
3.48M
    d_m3PreloadNext ();                                 \
311
3.48M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
3.48M
    nextOpPreloaded ();                                 \
313
3.48M
}
m3_compile.c:op_i64_Divide_ss
Line
Count
Source
306
27.3k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
27.3k
{                                                       \
308
27.3k
    TYPE operand2 = slot (TYPE);                        \
309
27.3k
    TYPE operand1 = slot (TYPE);                        \
310
27.3k
    d_m3PreloadNext ();                                 \
311
27.3k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
27.3k
    nextOpPreloaded ();                                 \
313
27.3k
}
m3_compile.c:op_u64_Divide_ss
Line
Count
Source
306
18.5k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
18.5k
{                                                       \
308
18.5k
    TYPE operand2 = slot (TYPE);                        \
309
18.5k
    TYPE operand1 = slot (TYPE);                        \
310
18.5k
    d_m3PreloadNext ();                                 \
311
18.5k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
18.5k
    nextOpPreloaded ();                                 \
313
18.5k
}
m3_compile.c:op_i64_Remainder_ss
Line
Count
Source
306
21.0k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
21.0k
{                                                       \
308
21.0k
    TYPE operand2 = slot (TYPE);                        \
309
21.0k
    TYPE operand1 = slot (TYPE);                        \
310
21.0k
    d_m3PreloadNext ();                                 \
311
21.0k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
21.0k
    nextOpPreloaded ();                                 \
313
21.0k
}
m3_compile.c:op_u64_Remainder_ss
Line
Count
Source
306
19.3k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
19.3k
{                                                       \
308
19.3k
    TYPE operand2 = slot (TYPE);                        \
309
19.3k
    TYPE operand1 = slot (TYPE);                        \
310
19.3k
    d_m3PreloadNext ();                                 \
311
19.3k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
19.3k
    nextOpPreloaded ();                                 \
313
19.3k
}
m3_compile.c:op_u64_And_ss
Line
Count
Source
306
1.47M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.47M
{                                                       \
308
1.47M
    TYPE operand2 = slot (TYPE);                        \
309
1.47M
    TYPE operand1 = slot (TYPE);                        \
310
1.47M
    d_m3PreloadNext ();                                 \
311
1.47M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.47M
    nextOpPreloaded ();                                 \
313
1.47M
}
m3_compile.c:op_u64_Or_ss
Line
Count
Source
306
1.75M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.75M
{                                                       \
308
1.75M
    TYPE operand2 = slot (TYPE);                        \
309
1.75M
    TYPE operand1 = slot (TYPE);                        \
310
1.75M
    d_m3PreloadNext ();                                 \
311
1.75M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.75M
    nextOpPreloaded ();                                 \
313
1.75M
}
m3_compile.c:op_u64_Xor_ss
Line
Count
Source
306
1.55M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.55M
{                                                       \
308
1.55M
    TYPE operand2 = slot (TYPE);                        \
309
1.55M
    TYPE operand1 = slot (TYPE);                        \
310
1.55M
    d_m3PreloadNext ();                                 \
311
1.55M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.55M
    nextOpPreloaded ();                                 \
313
1.55M
}
m3_compile.c:op_u64_ShiftLeft_ss
Line
Count
Source
306
1.23M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.23M
{                                                       \
308
1.23M
    TYPE operand2 = slot (TYPE);                        \
309
1.23M
    TYPE operand1 = slot (TYPE);                        \
310
1.23M
    d_m3PreloadNext ();                                 \
311
1.23M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.23M
    nextOpPreloaded ();                                 \
313
1.23M
}
m3_compile.c:op_i64_ShiftRight_ss
Line
Count
Source
306
1.00M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.00M
{                                                       \
308
1.00M
    TYPE operand2 = slot (TYPE);                        \
309
1.00M
    TYPE operand1 = slot (TYPE);                        \
310
1.00M
    d_m3PreloadNext ();                                 \
311
1.00M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.00M
    nextOpPreloaded ();                                 \
313
1.00M
}
m3_compile.c:op_u64_ShiftRight_ss
Line
Count
Source
306
936k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
936k
{                                                       \
308
936k
    TYPE operand2 = slot (TYPE);                        \
309
936k
    TYPE operand1 = slot (TYPE);                        \
310
936k
    d_m3PreloadNext ();                                 \
311
936k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
936k
    nextOpPreloaded ();                                 \
313
936k
}
m3_compile.c:op_u64_Rotl_ss
Line
Count
Source
306
1.59M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.59M
{                                                       \
308
1.59M
    TYPE operand2 = slot (TYPE);                        \
309
1.59M
    TYPE operand1 = slot (TYPE);                        \
310
1.59M
    d_m3PreloadNext ();                                 \
311
1.59M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.59M
    nextOpPreloaded ();                                 \
313
1.59M
}
m3_compile.c:op_u64_Rotr_ss
Line
Count
Source
306
1.07M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.07M
{                                                       \
308
1.07M
    TYPE operand2 = slot (TYPE);                        \
309
1.07M
    TYPE operand1 = slot (TYPE);                        \
310
1.07M
    d_m3PreloadNext ();                                 \
311
1.07M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.07M
    nextOpPreloaded ();                                 \
313
1.07M
}
m3_compile.c:op_f32_Add_ss
Line
Count
Source
306
824k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
824k
{                                                       \
308
824k
    TYPE operand2 = slot (TYPE);                        \
309
824k
    TYPE operand1 = slot (TYPE);                        \
310
824k
    d_m3PreloadNext ();                                 \
311
824k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
824k
    nextOpPreloaded ();                                 \
313
824k
}
m3_compile.c:op_f32_Subtract_ss
Line
Count
Source
306
762k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
762k
{                                                       \
308
762k
    TYPE operand2 = slot (TYPE);                        \
309
762k
    TYPE operand1 = slot (TYPE);                        \
310
762k
    d_m3PreloadNext ();                                 \
311
762k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
762k
    nextOpPreloaded ();                                 \
313
762k
}
m3_compile.c:op_f32_Multiply_ss
Line
Count
Source
306
1.14M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
1.14M
{                                                       \
308
1.14M
    TYPE operand2 = slot (TYPE);                        \
309
1.14M
    TYPE operand1 = slot (TYPE);                        \
310
1.14M
    d_m3PreloadNext ();                                 \
311
1.14M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
1.14M
    nextOpPreloaded ();                                 \
313
1.14M
}
m3_compile.c:op_f32_Divide_ss
Line
Count
Source
306
7.10k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
7.10k
{                                                       \
308
7.10k
    TYPE operand2 = slot (TYPE);                        \
309
7.10k
    TYPE operand1 = slot (TYPE);                        \
310
7.10k
    d_m3PreloadNext ();                                 \
311
7.10k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
7.10k
    nextOpPreloaded ();                                 \
313
7.10k
}
m3_compile.c:op_f32_Min_ss
Line
Count
Source
306
2.21M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.21M
{                                                       \
308
2.21M
    TYPE operand2 = slot (TYPE);                        \
309
2.21M
    TYPE operand1 = slot (TYPE);                        \
310
2.21M
    d_m3PreloadNext ();                                 \
311
2.21M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.21M
    nextOpPreloaded ();                                 \
313
2.21M
}
m3_compile.c:op_f32_Max_ss
Line
Count
Source
306
2.17M
d_m3Op(TYPE##_##NAME##_ss)                              \
307
2.17M
{                                                       \
308
2.17M
    TYPE operand2 = slot (TYPE);                        \
309
2.17M
    TYPE operand1 = slot (TYPE);                        \
310
2.17M
    d_m3PreloadNext ();                                 \
311
2.17M
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
2.17M
    nextOpPreloaded ();                                 \
313
2.17M
}
m3_compile.c:op_f32_CopySign_ss
Line
Count
Source
306
472k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
472k
{                                                       \
308
472k
    TYPE operand2 = slot (TYPE);                        \
309
472k
    TYPE operand1 = slot (TYPE);                        \
310
472k
    d_m3PreloadNext ();                                 \
311
472k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
472k
    nextOpPreloaded ();                                 \
313
472k
}
m3_compile.c:op_f64_Add_ss
Line
Count
Source
306
389k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
389k
{                                                       \
308
389k
    TYPE operand2 = slot (TYPE);                        \
309
389k
    TYPE operand1 = slot (TYPE);                        \
310
389k
    d_m3PreloadNext ();                                 \
311
389k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
389k
    nextOpPreloaded ();                                 \
313
389k
}
m3_compile.c:op_f64_Subtract_ss
Line
Count
Source
306
245k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
245k
{                                                       \
308
245k
    TYPE operand2 = slot (TYPE);                        \
309
245k
    TYPE operand1 = slot (TYPE);                        \
310
245k
    d_m3PreloadNext ();                                 \
311
245k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
245k
    nextOpPreloaded ();                                 \
313
245k
}
m3_compile.c:op_f64_Multiply_ss
Line
Count
Source
306
370k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
370k
{                                                       \
308
370k
    TYPE operand2 = slot (TYPE);                        \
309
370k
    TYPE operand1 = slot (TYPE);                        \
310
370k
    d_m3PreloadNext ();                                 \
311
370k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
370k
    nextOpPreloaded ();                                 \
313
370k
}
m3_compile.c:op_f64_Divide_ss
Line
Count
Source
306
8.62k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
8.62k
{                                                       \
308
8.62k
    TYPE operand2 = slot (TYPE);                        \
309
8.62k
    TYPE operand1 = slot (TYPE);                        \
310
8.62k
    d_m3PreloadNext ();                                 \
311
8.62k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
8.62k
    nextOpPreloaded ();                                 \
313
8.62k
}
m3_compile.c:op_f64_Min_ss
Line
Count
Source
306
778k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
778k
{                                                       \
308
778k
    TYPE operand2 = slot (TYPE);                        \
309
778k
    TYPE operand1 = slot (TYPE);                        \
310
778k
    d_m3PreloadNext ();                                 \
311
778k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
778k
    nextOpPreloaded ();                                 \
313
778k
}
m3_compile.c:op_f64_Max_ss
Line
Count
Source
306
711k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
711k
{                                                       \
308
711k
    TYPE operand2 = slot (TYPE);                        \
309
711k
    TYPE operand1 = slot (TYPE);                        \
310
711k
    d_m3PreloadNext ();                                 \
311
711k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
711k
    nextOpPreloaded ();                                 \
313
711k
}
m3_compile.c:op_f64_CopySign_ss
Line
Count
Source
306
310k
d_m3Op(TYPE##_##NAME##_ss)                              \
307
310k
{                                                       \
308
310k
    TYPE operand2 = slot (TYPE);                        \
309
310k
    TYPE operand1 = slot (TYPE);                        \
310
310k
    d_m3PreloadNext ();                                 \
311
310k
    OP((RES), operand1, operand2, ##__VA_ARGS__);       \
312
310k
    nextOpPreloaded ();                                 \
313
310k
}
314
315
#define d_m3OpMacro(RES, REG, TYPE, NAME, OP, ...)      \
316
38.7M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
38.7M
{                                                       \
318
38.7M
    TYPE operand = slot (TYPE);                         \
319
38.7M
    d_m3PreloadNext ();                                 \
320
38.7M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
38.7M
    nextOpPreloaded ();                                 \
322
33.1k
}                                                       \
m3_compile.c:op_i32_LessThan_sr
Line
Count
Source
316
1.72M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.72M
{                                                       \
318
1.72M
    TYPE operand = slot (TYPE);                         \
319
1.72M
    d_m3PreloadNext ();                                 \
320
1.72M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.72M
    nextOpPreloaded ();                                 \
322
1.72M
}                                                       \
m3_compile.c:op_u32_LessThan_sr
Line
Count
Source
316
2.31M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
2.31M
{                                                       \
318
2.31M
    TYPE operand = slot (TYPE);                         \
319
2.31M
    d_m3PreloadNext ();                                 \
320
2.31M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
2.31M
    nextOpPreloaded ();                                 \
322
2.31M
}                                                       \
m3_compile.c:op_i32_GreaterThan_sr
Line
Count
Source
316
2.05M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
2.05M
{                                                       \
318
2.05M
    TYPE operand = slot (TYPE);                         \
319
2.05M
    d_m3PreloadNext ();                                 \
320
2.05M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
2.05M
    nextOpPreloaded ();                                 \
322
2.05M
}                                                       \
m3_compile.c:op_u32_GreaterThan_sr
Line
Count
Source
316
1.88M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.88M
{                                                       \
318
1.88M
    TYPE operand = slot (TYPE);                         \
319
1.88M
    d_m3PreloadNext ();                                 \
320
1.88M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.88M
    nextOpPreloaded ();                                 \
322
1.88M
}                                                       \
m3_compile.c:op_i32_LessThanOrEqual_sr
Line
Count
Source
316
1.89M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.89M
{                                                       \
318
1.89M
    TYPE operand = slot (TYPE);                         \
319
1.89M
    d_m3PreloadNext ();                                 \
320
1.89M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.89M
    nextOpPreloaded ();                                 \
322
1.89M
}                                                       \
m3_compile.c:op_u32_LessThanOrEqual_sr
Line
Count
Source
316
1.62M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.62M
{                                                       \
318
1.62M
    TYPE operand = slot (TYPE);                         \
319
1.62M
    d_m3PreloadNext ();                                 \
320
1.62M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.62M
    nextOpPreloaded ();                                 \
322
1.62M
}                                                       \
m3_compile.c:op_i32_GreaterThanOrEqual_sr
Line
Count
Source
316
2.38M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
2.38M
{                                                       \
318
2.38M
    TYPE operand = slot (TYPE);                         \
319
2.38M
    d_m3PreloadNext ();                                 \
320
2.38M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
2.38M
    nextOpPreloaded ();                                 \
322
2.38M
}                                                       \
m3_compile.c:op_u32_GreaterThanOrEqual_sr
Line
Count
Source
316
1.53M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.53M
{                                                       \
318
1.53M
    TYPE operand = slot (TYPE);                         \
319
1.53M
    d_m3PreloadNext ();                                 \
320
1.53M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.53M
    nextOpPreloaded ();                                 \
322
1.53M
}                                                       \
m3_compile.c:op_i64_LessThan_sr
Line
Count
Source
316
999k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
999k
{                                                       \
318
999k
    TYPE operand = slot (TYPE);                         \
319
999k
    d_m3PreloadNext ();                                 \
320
999k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
999k
    nextOpPreloaded ();                                 \
322
999k
}                                                       \
m3_compile.c:op_u64_LessThan_sr
Line
Count
Source
316
1.24M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.24M
{                                                       \
318
1.24M
    TYPE operand = slot (TYPE);                         \
319
1.24M
    d_m3PreloadNext ();                                 \
320
1.24M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.24M
    nextOpPreloaded ();                                 \
322
1.24M
}                                                       \
m3_compile.c:op_i64_GreaterThan_sr
Line
Count
Source
316
1.19M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.19M
{                                                       \
318
1.19M
    TYPE operand = slot (TYPE);                         \
319
1.19M
    d_m3PreloadNext ();                                 \
320
1.19M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.19M
    nextOpPreloaded ();                                 \
322
1.19M
}                                                       \
m3_compile.c:op_u64_GreaterThan_sr
Line
Count
Source
316
1.07M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.07M
{                                                       \
318
1.07M
    TYPE operand = slot (TYPE);                         \
319
1.07M
    d_m3PreloadNext ();                                 \
320
1.07M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.07M
    nextOpPreloaded ();                                 \
322
1.07M
}                                                       \
m3_compile.c:op_i64_LessThanOrEqual_sr
Line
Count
Source
316
1.32M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.32M
{                                                       \
318
1.32M
    TYPE operand = slot (TYPE);                         \
319
1.32M
    d_m3PreloadNext ();                                 \
320
1.32M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.32M
    nextOpPreloaded ();                                 \
322
1.32M
}                                                       \
m3_compile.c:op_u64_LessThanOrEqual_sr
Line
Count
Source
316
992k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
992k
{                                                       \
318
992k
    TYPE operand = slot (TYPE);                         \
319
992k
    d_m3PreloadNext ();                                 \
320
992k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
992k
    nextOpPreloaded ();                                 \
322
992k
}                                                       \
m3_compile.c:op_i64_GreaterThanOrEqual_sr
Line
Count
Source
316
865k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
865k
{                                                       \
318
865k
    TYPE operand = slot (TYPE);                         \
319
865k
    d_m3PreloadNext ();                                 \
320
865k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
865k
    nextOpPreloaded ();                                 \
322
865k
}                                                       \
m3_compile.c:op_u64_GreaterThanOrEqual_sr
Line
Count
Source
316
861k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
861k
{                                                       \
318
861k
    TYPE operand = slot (TYPE);                         \
319
861k
    d_m3PreloadNext ();                                 \
320
861k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
861k
    nextOpPreloaded ();                                 \
322
861k
}                                                       \
m3_compile.c:op_f32_LessThan_sr
Line
Count
Source
316
415k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
415k
{                                                       \
318
415k
    TYPE operand = slot (TYPE);                         \
319
415k
    d_m3PreloadNext ();                                 \
320
415k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
415k
    nextOpPreloaded ();                                 \
322
415k
}                                                       \
m3_compile.c:op_f32_GreaterThan_sr
Line
Count
Source
316
421k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
421k
{                                                       \
318
421k
    TYPE operand = slot (TYPE);                         \
319
421k
    d_m3PreloadNext ();                                 \
320
421k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
421k
    nextOpPreloaded ();                                 \
322
421k
}                                                       \
m3_compile.c:op_f32_LessThanOrEqual_sr
Line
Count
Source
316
352k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
352k
{                                                       \
318
352k
    TYPE operand = slot (TYPE);                         \
319
352k
    d_m3PreloadNext ();                                 \
320
352k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
352k
    nextOpPreloaded ();                                 \
322
352k
}                                                       \
m3_compile.c:op_f32_GreaterThanOrEqual_sr
Line
Count
Source
316
629k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
629k
{                                                       \
318
629k
    TYPE operand = slot (TYPE);                         \
319
629k
    d_m3PreloadNext ();                                 \
320
629k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
629k
    nextOpPreloaded ();                                 \
322
629k
}                                                       \
m3_compile.c:op_f64_LessThan_sr
Line
Count
Source
316
221k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
221k
{                                                       \
318
221k
    TYPE operand = slot (TYPE);                         \
319
221k
    d_m3PreloadNext ();                                 \
320
221k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
221k
    nextOpPreloaded ();                                 \
322
221k
}                                                       \
m3_compile.c:op_f64_GreaterThan_sr
Line
Count
Source
316
337k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
337k
{                                                       \
318
337k
    TYPE operand = slot (TYPE);                         \
319
337k
    d_m3PreloadNext ();                                 \
320
337k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
337k
    nextOpPreloaded ();                                 \
322
337k
}                                                       \
m3_compile.c:op_f64_LessThanOrEqual_sr
Line
Count
Source
316
268k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
268k
{                                                       \
318
268k
    TYPE operand = slot (TYPE);                         \
319
268k
    d_m3PreloadNext ();                                 \
320
268k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
268k
    nextOpPreloaded ();                                 \
322
268k
}                                                       \
m3_compile.c:op_f64_GreaterThanOrEqual_sr
Line
Count
Source
316
432k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
432k
{                                                       \
318
432k
    TYPE operand = slot (TYPE);                         \
319
432k
    d_m3PreloadNext ();                                 \
320
432k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
432k
    nextOpPreloaded ();                                 \
322
432k
}                                                       \
m3_compile.c:op_i32_Subtract_sr
Line
Count
Source
316
1.64M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.64M
{                                                       \
318
1.64M
    TYPE operand = slot (TYPE);                         \
319
1.64M
    d_m3PreloadNext ();                                 \
320
1.64M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.64M
    nextOpPreloaded ();                                 \
322
1.64M
}                                                       \
m3_compile.c:op_i32_Divide_sr
Line
Count
Source
316
15.4k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
15.4k
{                                                       \
318
15.4k
    TYPE operand = slot (TYPE);                         \
319
15.4k
    d_m3PreloadNext ();                                 \
320
15.4k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
15.4k
    nextOpPreloaded ();                                 \
322
15.4k
}                                                       \
m3_compile.c:op_u32_Divide_sr
Line
Count
Source
316
15.8k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
15.8k
{                                                       \
318
15.8k
    TYPE operand = slot (TYPE);                         \
319
15.8k
    d_m3PreloadNext ();                                 \
320
15.8k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
15.7k
    nextOpPreloaded ();                                 \
322
15.8k
}                                                       \
m3_compile.c:op_i32_Remainder_sr
Line
Count
Source
316
15.0k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
15.0k
{                                                       \
318
15.0k
    TYPE operand = slot (TYPE);                         \
319
15.0k
    d_m3PreloadNext ();                                 \
320
15.0k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
15.0k
    nextOpPreloaded ();                                 \
322
15.0k
}                                                       \
m3_compile.c:op_u32_Remainder_sr
Line
Count
Source
316
15.2k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
15.2k
{                                                       \
318
15.2k
    TYPE operand = slot (TYPE);                         \
319
15.2k
    d_m3PreloadNext ();                                 \
320
15.2k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
15.2k
    nextOpPreloaded ();                                 \
322
15.2k
}                                                       \
m3_compile.c:op_u32_ShiftLeft_sr
Line
Count
Source
316
866k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
866k
{                                                       \
318
866k
    TYPE operand = slot (TYPE);                         \
319
866k
    d_m3PreloadNext ();                                 \
320
866k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
866k
    nextOpPreloaded ();                                 \
322
866k
}                                                       \
m3_compile.c:op_i32_ShiftRight_sr
Line
Count
Source
316
878k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
878k
{                                                       \
318
878k
    TYPE operand = slot (TYPE);                         \
319
878k
    d_m3PreloadNext ();                                 \
320
878k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
878k
    nextOpPreloaded ();                                 \
322
878k
}                                                       \
m3_compile.c:op_u32_ShiftRight_sr
Line
Count
Source
316
727k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
727k
{                                                       \
318
727k
    TYPE operand = slot (TYPE);                         \
319
727k
    d_m3PreloadNext ();                                 \
320
727k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
727k
    nextOpPreloaded ();                                 \
322
727k
}                                                       \
m3_compile.c:op_u32_Rotl_sr
Line
Count
Source
316
725k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
725k
{                                                       \
318
725k
    TYPE operand = slot (TYPE);                         \
319
725k
    d_m3PreloadNext ();                                 \
320
725k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
725k
    nextOpPreloaded ();                                 \
322
725k
}                                                       \
m3_compile.c:op_u32_Rotr_sr
Line
Count
Source
316
1.53M
d_m3Op(TYPE##_##NAME##_sr)                              \
317
1.53M
{                                                       \
318
1.53M
    TYPE operand = slot (TYPE);                         \
319
1.53M
    d_m3PreloadNext ();                                 \
320
1.53M
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
1.53M
    nextOpPreloaded ();                                 \
322
1.53M
}                                                       \
m3_compile.c:op_i64_Subtract_sr
Line
Count
Source
316
473k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
473k
{                                                       \
318
473k
    TYPE operand = slot (TYPE);                         \
319
473k
    d_m3PreloadNext ();                                 \
320
473k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
473k
    nextOpPreloaded ();                                 \
322
473k
}                                                       \
m3_compile.c:op_i64_Divide_sr
Line
Count
Source
316
17.7k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
17.7k
{                                                       \
318
17.7k
    TYPE operand = slot (TYPE);                         \
319
17.7k
    d_m3PreloadNext ();                                 \
320
17.7k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
17.7k
    nextOpPreloaded ();                                 \
322
17.7k
}                                                       \
m3_compile.c:op_u64_Divide_sr
Line
Count
Source
316
13.2k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
13.2k
{                                                       \
318
13.2k
    TYPE operand = slot (TYPE);                         \
319
13.2k
    d_m3PreloadNext ();                                 \
320
13.2k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
13.2k
    nextOpPreloaded ();                                 \
322
13.2k
}                                                       \
m3_compile.c:op_i64_Remainder_sr
Line
Count
Source
316
19.9k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
19.9k
{                                                       \
318
19.9k
    TYPE operand = slot (TYPE);                         \
319
19.9k
    d_m3PreloadNext ();                                 \
320
19.9k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
19.9k
    nextOpPreloaded ();                                 \
322
19.9k
}                                                       \
m3_compile.c:op_u64_Remainder_sr
Line
Count
Source
316
13.1k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
13.1k
{                                                       \
318
13.1k
    TYPE operand = slot (TYPE);                         \
319
13.1k
    d_m3PreloadNext ();                                 \
320
13.1k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
13.1k
    nextOpPreloaded ();                                 \
322
13.1k
}                                                       \
m3_compile.c:op_u64_ShiftLeft_sr
Line
Count
Source
316
818k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
818k
{                                                       \
318
818k
    TYPE operand = slot (TYPE);                         \
319
818k
    d_m3PreloadNext ();                                 \
320
818k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
818k
    nextOpPreloaded ();                                 \
322
818k
}                                                       \
m3_compile.c:op_i64_ShiftRight_sr
Line
Count
Source
316
500k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
500k
{                                                       \
318
500k
    TYPE operand = slot (TYPE);                         \
319
500k
    d_m3PreloadNext ();                                 \
320
500k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
500k
    nextOpPreloaded ();                                 \
322
500k
}                                                       \
m3_compile.c:op_u64_ShiftRight_sr
Line
Count
Source
316
432k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
432k
{                                                       \
318
432k
    TYPE operand = slot (TYPE);                         \
319
432k
    d_m3PreloadNext ();                                 \
320
432k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
432k
    nextOpPreloaded ();                                 \
322
432k
}                                                       \
m3_compile.c:op_u64_Rotl_sr
Line
Count
Source
316
783k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
783k
{                                                       \
318
783k
    TYPE operand = slot (TYPE);                         \
319
783k
    d_m3PreloadNext ();                                 \
320
783k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
783k
    nextOpPreloaded ();                                 \
322
783k
}                                                       \
m3_compile.c:op_u64_Rotr_sr
Line
Count
Source
316
410k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
410k
{                                                       \
318
410k
    TYPE operand = slot (TYPE);                         \
319
410k
    d_m3PreloadNext ();                                 \
320
410k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
410k
    nextOpPreloaded ();                                 \
322
410k
}                                                       \
m3_compile.c:op_f32_Subtract_sr
Line
Count
Source
316
592k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
592k
{                                                       \
318
592k
    TYPE operand = slot (TYPE);                         \
319
592k
    d_m3PreloadNext ();                                 \
320
592k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
592k
    nextOpPreloaded ();                                 \
322
592k
}                                                       \
m3_compile.c:op_f32_Divide_sr
Line
Count
Source
316
3.60k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
3.60k
{                                                       \
318
3.60k
    TYPE operand = slot (TYPE);                         \
319
3.60k
    d_m3PreloadNext ();                                 \
320
3.60k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
3.60k
    nextOpPreloaded ();                                 \
322
3.60k
}                                                       \
m3_compile.c:op_f32_CopySign_sr
Line
Count
Source
316
351k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
351k
{                                                       \
318
351k
    TYPE operand = slot (TYPE);                         \
319
351k
    d_m3PreloadNext ();                                 \
320
351k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
351k
    nextOpPreloaded ();                                 \
322
351k
}                                                       \
m3_compile.c:op_f64_Subtract_sr
Line
Count
Source
316
472k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
472k
{                                                       \
318
472k
    TYPE operand = slot (TYPE);                         \
319
472k
    d_m3PreloadNext ();                                 \
320
472k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
472k
    nextOpPreloaded ();                                 \
322
472k
}                                                       \
m3_compile.c:op_f64_Divide_sr
Line
Count
Source
316
3.71k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
3.71k
{                                                       \
318
3.71k
    TYPE operand = slot (TYPE);                         \
319
3.71k
    d_m3PreloadNext ();                                 \
320
3.71k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
3.71k
    nextOpPreloaded ();                                 \
322
3.71k
}                                                       \
m3_compile.c:op_f64_CopySign_sr
Line
Count
Source
316
315k
d_m3Op(TYPE##_##NAME##_sr)                              \
317
315k
{                                                       \
318
315k
    TYPE operand = slot (TYPE);                         \
319
315k
    d_m3PreloadNext ();                                 \
320
315k
    OP((RES), ((TYPE) REG), operand, ##__VA_ARGS__);    \
321
315k
    nextOpPreloaded ();                                 \
322
315k
}                                                       \
Unexecuted instantiation: m3_compile.c:op_f32_Min_sr
Unexecuted instantiation: m3_compile.c:op_f32_Max_sr
Unexecuted instantiation: m3_compile.c:op_f64_Min_sr
Unexecuted instantiation: m3_compile.c:op_f64_Max_sr
323
d_m3CommutativeOpMacro(RES, REG, TYPE,NAME, OP, ##__VA_ARGS__)
324
325
// Accept macros
326
#define d_m3CommutativeOpMacro_i(TYPE, NAME, MACRO, ...)    d_m3CommutativeOpMacro  ( _r0,  _r0, TYPE, NAME, MACRO, ##__VA_ARGS__)
327
#define d_m3OpMacro_i(TYPE, NAME, MACRO, ...)               d_m3OpMacro             ( _r0,  _r0, TYPE, NAME, MACRO, ##__VA_ARGS__)
328
#define d_m3CommutativeOpMacro_f(TYPE, NAME, MACRO, ...)    d_m3CommutativeOpMacro  (_fp0, _fp0, TYPE, NAME, MACRO, ##__VA_ARGS__)
329
#define d_m3OpMacro_f(TYPE, NAME, MACRO, ...)               d_m3OpMacro             (_fp0, _fp0, TYPE, NAME, MACRO, ##__VA_ARGS__)
330
331
63.7M
#define M3_FUNC(RES, A, B, OP)  (RES) = OP((A), (B))        // Accept functions: res = OP(a,b)
332
137M
#define M3_OPER(RES, A, B, OP)  (RES) = ((A) OP (B))        // Accept operators: res = a OP b
333
334
// The same two, for a float operation whose NaN result the spec leaves to the host:
335
// CANON is the canonicalizer for the operation's width (only in effect when d_m3CanonicalNaN is set).
336
11.1M
#define M3_FUNC_A(RES, A, B, OP, CANON)  (RES) = CANON(OP((A), (B)))
337
10.4M
#define M3_OPER_A(RES, A, B, OP, CANON)  (RES) = CANON((A) OP (B))
338
339
16.3M
#define d_m3CommutativeOpFunc_i(TYPE, NAME, OP)     d_m3CommutativeOpMacro_i    (TYPE, NAME, M3_FUNC, OP)
340
37.7M
#define d_m3OpFunc_i(TYPE, NAME, OP)                d_m3OpMacro_i               (TYPE, NAME, M3_FUNC, OP)
341
#define d_m3CommutativeOpFunc_f(TYPE, NAME, OP)     d_m3CommutativeOpMacro_f    (TYPE, NAME, M3_FUNC, OP)
342
1.94M
#define d_m3OpFunc_f(TYPE, NAME, OP)                d_m3OpMacro_f               (TYPE, NAME, M3_FUNC, OP)
343
344
33.2M
#define d_m3CommutativeOp_i(TYPE, NAME, OP)         d_m3CommutativeOpMacro_i    (TYPE, NAME, M3_OPER, OP)
345
87.0M
#define d_m3Op_i(TYPE, NAME, OP)                    d_m3OpMacro_i               (TYPE, NAME, M3_OPER, OP)
346
#define d_m3CommutativeOp_f(TYPE, NAME, OP)         d_m3CommutativeOpMacro_f    (TYPE, NAME, M3_OPER, OP)
347
#define d_m3Op_f(TYPE, NAME, OP)                    d_m3OpMacro_f               (TYPE, NAME, M3_OPER, OP)
348
349
// ...and the arithmetic ones, which name the canonicalizer for their own width
350
5.15M
#define d_m3CommutativeArithOp_f(TYPE, NAME, OP)    d_m3CommutativeOpMacro_f    (TYPE, NAME, M3_OPER_A, OP, canon_nan_##TYPE)
351
3.25M
#define d_m3ArithOp_f(TYPE, NAME, OP)               d_m3OpMacro_f               (TYPE, NAME, M3_OPER_A, OP, canon_nan_##TYPE)
352
11.1M
#define d_m3ArithOpFunc_f(TYPE, NAME, OP)           d_m3OpMacro_f               (TYPE, NAME, M3_FUNC_A, OP, canon_nan_##TYPE)
353
354
// compare needs to be distinct for fp 'cause the result must be _r0
355
10.2M
#define d_m3CompareOp_f(TYPE, NAME, OP)             d_m3OpMacro                 (_r0, _fp0, TYPE, NAME, M3_OPER, OP)
356
4.24M
#define d_m3CommutativeCmpOp_f(TYPE, NAME, OP)      d_m3CommutativeOpMacro      (_r0, _fp0, TYPE, NAME, M3_OPER, OP)
357
358
359
//-----------------------
360
// clang-format off
361
362
// signed
363
d_m3CommutativeOp_i(i32, Equal,            ==)     d_m3CommutativeOp_i(i64, Equal,            ==)
364
d_m3CommutativeOp_i(i32, NotEqual,         !=)     d_m3CommutativeOp_i(i64, NotEqual,         !=)
365
366
d_m3Op_i(i32, LessThan,                    < )     d_m3Op_i(i64, LessThan,                    < )
367
d_m3Op_i(i32, GreaterThan,                 > )     d_m3Op_i(i64, GreaterThan,                 > )
368
d_m3Op_i(i32, LessThanOrEqual,             <=)     d_m3Op_i(i64, LessThanOrEqual,             <=)
369
d_m3Op_i(i32, GreaterThanOrEqual,          >=)     d_m3Op_i(i64, GreaterThanOrEqual,          >=)
370
371
// unsigned
372
d_m3Op_i(u32, LessThan,                    < )     d_m3Op_i(u64, LessThan,                    < )
373
d_m3Op_i(u32, GreaterThan,                 > )     d_m3Op_i(u64, GreaterThan,                 > )
374
d_m3Op_i(u32, LessThanOrEqual,             <=)     d_m3Op_i(u64, LessThanOrEqual,             <=)
375
d_m3Op_i(u32, GreaterThanOrEqual,          >=)     d_m3Op_i(u64, GreaterThanOrEqual,          >=)
376
377
#if d_m3HasFloat
378
d_m3CommutativeCmpOp_f(f32, Equal,         ==)     d_m3CommutativeCmpOp_f(f64, Equal,         ==)
379
d_m3CommutativeCmpOp_f(f32, NotEqual,      !=)     d_m3CommutativeCmpOp_f(f64, NotEqual,      !=)
380
d_m3CompareOp_f(f32, LessThan,             < )     d_m3CompareOp_f(f64, LessThan,             < )
381
d_m3CompareOp_f(f32, GreaterThan,          > )     d_m3CompareOp_f(f64, GreaterThan,          > )
382
d_m3CompareOp_f(f32, LessThanOrEqual,      <=)     d_m3CompareOp_f(f64, LessThanOrEqual,      <=)
383
d_m3CompareOp_f(f32, GreaterThanOrEqual,   >=)     d_m3CompareOp_f(f64, GreaterThanOrEqual,   >=)
384
#endif
385
386
4.08M
#define OP_ADD_32(A,B) (i32)((u32)(A) + (u32)(B))
387
4.35M
#define OP_ADD_64(A,B) (i64)((u64)(A) + (u64)(B))
388
5.01M
#define OP_SUB_32(A,B) (i32)((u32)(A) - (u32)(B))
389
4.21M
#define OP_SUB_64(A,B) (i64)((u64)(A) - (u64)(B))
390
4.18M
#define OP_MUL_32(A,B) (i32)((u32)(A) * (u32)(B))
391
6.06M
#define OP_MUL_64(A,B) (i64)((u64)(A) * (u64)(B))
392
393
3.83M
d_m3CommutativeOpFunc_i (i32, Add,      OP_ADD_32)  d_m3CommutativeOpFunc_i (i64, Add,      OP_ADD_64)
394
5.26M
d_m3CommutativeOpFunc_i (i32, Multiply, OP_MUL_32)  d_m3CommutativeOpFunc_i (i64, Multiply, OP_MUL_64)
395
396
4.41M
d_m3OpFunc_i (i32, Subtract,            OP_SUB_32)  d_m3OpFunc_i (i64, Subtract,            OP_SUB_64)
397
398
4.32M
#define OP_SHL_32(X,N) ((X) << ((u32)(N) % 32))
399
3.44M
#define OP_SHL_64(X,N) ((X) << ((u64)(N) % 64))
400
7.01M
#define OP_SHR_32(X,N) ((X) >> ((u32)(N) % 32))
401
5.43M
#define OP_SHR_64(X,N) ((X) >> ((u64)(N) % 64))
402
403
3.56M
d_m3OpFunc_i (u32, ShiftLeft,       OP_SHL_32)      d_m3OpFunc_i (u64, ShiftLeft,       OP_SHL_64)
404
2.93M
d_m3OpFunc_i (i32, ShiftRight,      OP_SHR_32)      d_m3OpFunc_i (i64, ShiftRight,      OP_SHR_64)
405
2.50M
d_m3OpFunc_i (u32, ShiftRight,      OP_SHR_32)      d_m3OpFunc_i (u64, ShiftRight,      OP_SHR_64)
406
407
d_m3CommutativeOp_i(u32, And,              &)
408
d_m3CommutativeOp_i(u32, Or,               |)
409
d_m3CommutativeOp_i(u32, Xor,              ^)
410
411
d_m3CommutativeOp_i(u64, And,              &)
412
d_m3CommutativeOp_i(u64, Or,               |)
413
d_m3CommutativeOp_i(u64, Xor,              ^)
414
415
#if d_m3FoldSetLocal
416
417
// destination-folded ("_f") variants: same operand shapes as _rs/_sr/_ss, but the result is
418
// written to a trailing destination slot instead of _r0 - a producer fused with its local.set.
419
// operand immediates keep their normal order; the destination slot is the last immediate.
420
// The destination immediate is taken as a pointer before the operation runs, rather
421
// than written through at the end: that leaves _pc final early enough for the dispatch
422
// load to be issued ahead of the arithmetic instead of after it.
423
// The result is written through to the register as well as to the destination slot.
424
// Destination folding only ever replaces an operation that computed into the register,
425
// so the old value there is already dead and keeping the result costs nothing -- and it
426
// lets a local.tee carry on in the register instead of reloading the slot it just wrote.
427
#  define d_m3FoldCommutativeOpMacro(REG, TYPE, NAME, OP, ...) \
428
5.03M
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
5.03M
{                                                       \
430
5.03M
    TYPE operand = slot (TYPE);                         \
431
5.03M
    TYPE * dest = slot_ptr (TYPE);                      \
432
5.03M
    d_m3PreloadNext ();                                 \
433
5.03M
    TYPE result;                                        \
434
5.03M
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
5.03M
    * dest = result;  REG = result;                     \
436
5.03M
    nextOpPreloaded ();                                 \
437
5.03M
}                                                       \
m3_compile.c:op_i32_Add_rs_f
Line
Count
Source
428
130k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
130k
{                                                       \
430
130k
    TYPE operand = slot (TYPE);                         \
431
130k
    TYPE * dest = slot_ptr (TYPE);                      \
432
130k
    d_m3PreloadNext ();                                 \
433
130k
    TYPE result;                                        \
434
130k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
130k
    * dest = result;  REG = result;                     \
436
130k
    nextOpPreloaded ();                                 \
437
130k
}                                                       \
m3_compile.c:op_i32_Subtract_rs_f
Line
Count
Source
428
230k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
230k
{                                                       \
430
230k
    TYPE operand = slot (TYPE);                         \
431
230k
    TYPE * dest = slot_ptr (TYPE);                      \
432
230k
    d_m3PreloadNext ();                                 \
433
230k
    TYPE result;                                        \
434
230k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
230k
    * dest = result;  REG = result;                     \
436
230k
    nextOpPreloaded ();                                 \
437
230k
}                                                       \
m3_compile.c:op_i32_Multiply_rs_f
Line
Count
Source
428
347k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
347k
{                                                       \
430
347k
    TYPE operand = slot (TYPE);                         \
431
347k
    TYPE * dest = slot_ptr (TYPE);                      \
432
347k
    d_m3PreloadNext ();                                 \
433
347k
    TYPE result;                                        \
434
347k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
347k
    * dest = result;  REG = result;                     \
436
347k
    nextOpPreloaded ();                                 \
437
347k
}                                                       \
m3_compile.c:op_u32_And_rs_f
Line
Count
Source
428
286k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
286k
{                                                       \
430
286k
    TYPE operand = slot (TYPE);                         \
431
286k
    TYPE * dest = slot_ptr (TYPE);                      \
432
286k
    d_m3PreloadNext ();                                 \
433
286k
    TYPE result;                                        \
434
286k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
286k
    * dest = result;  REG = result;                     \
436
286k
    nextOpPreloaded ();                                 \
437
286k
}                                                       \
m3_compile.c:op_u32_Or_rs_f
Line
Count
Source
428
115k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
115k
{                                                       \
430
115k
    TYPE operand = slot (TYPE);                         \
431
115k
    TYPE * dest = slot_ptr (TYPE);                      \
432
115k
    d_m3PreloadNext ();                                 \
433
115k
    TYPE result;                                        \
434
115k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
115k
    * dest = result;  REG = result;                     \
436
115k
    nextOpPreloaded ();                                 \
437
115k
}                                                       \
m3_compile.c:op_u32_Xor_rs_f
Line
Count
Source
428
272k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
272k
{                                                       \
430
272k
    TYPE operand = slot (TYPE);                         \
431
272k
    TYPE * dest = slot_ptr (TYPE);                      \
432
272k
    d_m3PreloadNext ();                                 \
433
272k
    TYPE result;                                        \
434
272k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
272k
    * dest = result;  REG = result;                     \
436
272k
    nextOpPreloaded ();                                 \
437
272k
}                                                       \
m3_compile.c:op_u32_ShiftLeft_rs_f
Line
Count
Source
428
256k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
256k
{                                                       \
430
256k
    TYPE operand = slot (TYPE);                         \
431
256k
    TYPE * dest = slot_ptr (TYPE);                      \
432
256k
    d_m3PreloadNext ();                                 \
433
256k
    TYPE result;                                        \
434
256k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
256k
    * dest = result;  REG = result;                     \
436
256k
    nextOpPreloaded ();                                 \
437
256k
}                                                       \
m3_compile.c:op_i32_ShiftRight_rs_f
Line
Count
Source
428
227k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
227k
{                                                       \
430
227k
    TYPE operand = slot (TYPE);                         \
431
227k
    TYPE * dest = slot_ptr (TYPE);                      \
432
227k
    d_m3PreloadNext ();                                 \
433
227k
    TYPE result;                                        \
434
227k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
227k
    * dest = result;  REG = result;                     \
436
227k
    nextOpPreloaded ();                                 \
437
227k
}                                                       \
m3_compile.c:op_u32_ShiftRight_rs_f
Line
Count
Source
428
172k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
172k
{                                                       \
430
172k
    TYPE operand = slot (TYPE);                         \
431
172k
    TYPE * dest = slot_ptr (TYPE);                      \
432
172k
    d_m3PreloadNext ();                                 \
433
172k
    TYPE result;                                        \
434
172k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
172k
    * dest = result;  REG = result;                     \
436
172k
    nextOpPreloaded ();                                 \
437
172k
}                                                       \
m3_compile.c:op_i64_Add_rs_f
Line
Count
Source
428
332k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
332k
{                                                       \
430
332k
    TYPE operand = slot (TYPE);                         \
431
332k
    TYPE * dest = slot_ptr (TYPE);                      \
432
332k
    d_m3PreloadNext ();                                 \
433
332k
    TYPE result;                                        \
434
332k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
332k
    * dest = result;  REG = result;                     \
436
332k
    nextOpPreloaded ();                                 \
437
332k
}                                                       \
m3_compile.c:op_i64_Subtract_rs_f
Line
Count
Source
428
242k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
242k
{                                                       \
430
242k
    TYPE operand = slot (TYPE);                         \
431
242k
    TYPE * dest = slot_ptr (TYPE);                      \
432
242k
    d_m3PreloadNext ();                                 \
433
242k
    TYPE result;                                        \
434
242k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
242k
    * dest = result;  REG = result;                     \
436
242k
    nextOpPreloaded ();                                 \
437
242k
}                                                       \
m3_compile.c:op_i64_Multiply_rs_f
Line
Count
Source
428
345k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
345k
{                                                       \
430
345k
    TYPE operand = slot (TYPE);                         \
431
345k
    TYPE * dest = slot_ptr (TYPE);                      \
432
345k
    d_m3PreloadNext ();                                 \
433
345k
    TYPE result;                                        \
434
345k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
345k
    * dest = result;  REG = result;                     \
436
345k
    nextOpPreloaded ();                                 \
437
345k
}                                                       \
m3_compile.c:op_u64_And_rs_f
Line
Count
Source
428
325k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
325k
{                                                       \
430
325k
    TYPE operand = slot (TYPE);                         \
431
325k
    TYPE * dest = slot_ptr (TYPE);                      \
432
325k
    d_m3PreloadNext ();                                 \
433
325k
    TYPE result;                                        \
434
325k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
325k
    * dest = result;  REG = result;                     \
436
325k
    nextOpPreloaded ();                                 \
437
325k
}                                                       \
m3_compile.c:op_u64_Or_rs_f
Line
Count
Source
428
280k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
280k
{                                                       \
430
280k
    TYPE operand = slot (TYPE);                         \
431
280k
    TYPE * dest = slot_ptr (TYPE);                      \
432
280k
    d_m3PreloadNext ();                                 \
433
280k
    TYPE result;                                        \
434
280k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
280k
    * dest = result;  REG = result;                     \
436
280k
    nextOpPreloaded ();                                 \
437
280k
}                                                       \
m3_compile.c:op_u64_Xor_rs_f
Line
Count
Source
428
109k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
109k
{                                                       \
430
109k
    TYPE operand = slot (TYPE);                         \
431
109k
    TYPE * dest = slot_ptr (TYPE);                      \
432
109k
    d_m3PreloadNext ();                                 \
433
109k
    TYPE result;                                        \
434
109k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
109k
    * dest = result;  REG = result;                     \
436
109k
    nextOpPreloaded ();                                 \
437
109k
}                                                       \
m3_compile.c:op_u64_ShiftLeft_rs_f
Line
Count
Source
428
149k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
149k
{                                                       \
430
149k
    TYPE operand = slot (TYPE);                         \
431
149k
    TYPE * dest = slot_ptr (TYPE);                      \
432
149k
    d_m3PreloadNext ();                                 \
433
149k
    TYPE result;                                        \
434
149k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
149k
    * dest = result;  REG = result;                     \
436
149k
    nextOpPreloaded ();                                 \
437
149k
}                                                       \
m3_compile.c:op_i64_ShiftRight_rs_f
Line
Count
Source
428
96.9k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
96.9k
{                                                       \
430
96.9k
    TYPE operand = slot (TYPE);                         \
431
96.9k
    TYPE * dest = slot_ptr (TYPE);                      \
432
96.9k
    d_m3PreloadNext ();                                 \
433
96.9k
    TYPE result;                                        \
434
96.9k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
96.9k
    * dest = result;  REG = result;                     \
436
96.9k
    nextOpPreloaded ();                                 \
437
96.9k
}                                                       \
m3_compile.c:op_u64_ShiftRight_rs_f
Line
Count
Source
428
147k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
147k
{                                                       \
430
147k
    TYPE operand = slot (TYPE);                         \
431
147k
    TYPE * dest = slot_ptr (TYPE);                      \
432
147k
    d_m3PreloadNext ();                                 \
433
147k
    TYPE result;                                        \
434
147k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
147k
    * dest = result;  REG = result;                     \
436
147k
    nextOpPreloaded ();                                 \
437
147k
}                                                       \
m3_compile.c:op_f32_Add_rs_f
Line
Count
Source
428
95.9k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
95.9k
{                                                       \
430
95.9k
    TYPE operand = slot (TYPE);                         \
431
95.9k
    TYPE * dest = slot_ptr (TYPE);                      \
432
95.9k
    d_m3PreloadNext ();                                 \
433
95.9k
    TYPE result;                                        \
434
95.9k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
95.9k
    * dest = result;  REG = result;                     \
436
95.9k
    nextOpPreloaded ();                                 \
437
95.9k
}                                                       \
m3_compile.c:op_f32_Subtract_rs_f
Line
Count
Source
428
114k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
114k
{                                                       \
430
114k
    TYPE operand = slot (TYPE);                         \
431
114k
    TYPE * dest = slot_ptr (TYPE);                      \
432
114k
    d_m3PreloadNext ();                                 \
433
114k
    TYPE result;                                        \
434
114k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
114k
    * dest = result;  REG = result;                     \
436
114k
    nextOpPreloaded ();                                 \
437
114k
}                                                       \
m3_compile.c:op_f32_Multiply_rs_f
Line
Count
Source
428
209k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
209k
{                                                       \
430
209k
    TYPE operand = slot (TYPE);                         \
431
209k
    TYPE * dest = slot_ptr (TYPE);                      \
432
209k
    d_m3PreloadNext ();                                 \
433
209k
    TYPE result;                                        \
434
209k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
209k
    * dest = result;  REG = result;                     \
436
209k
    nextOpPreloaded ();                                 \
437
209k
}                                                       \
m3_compile.c:op_f32_Divide_rs_f
Line
Count
Source
428
2.89k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
2.89k
{                                                       \
430
2.89k
    TYPE operand = slot (TYPE);                         \
431
2.89k
    TYPE * dest = slot_ptr (TYPE);                      \
432
2.89k
    d_m3PreloadNext ();                                 \
433
2.89k
    TYPE result;                                        \
434
2.89k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
2.89k
    * dest = result;  REG = result;                     \
436
2.89k
    nextOpPreloaded ();                                 \
437
2.89k
}                                                       \
m3_compile.c:op_f64_Add_rs_f
Line
Count
Source
428
192k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
192k
{                                                       \
430
192k
    TYPE operand = slot (TYPE);                         \
431
192k
    TYPE * dest = slot_ptr (TYPE);                      \
432
192k
    d_m3PreloadNext ();                                 \
433
192k
    TYPE result;                                        \
434
192k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
192k
    * dest = result;  REG = result;                     \
436
192k
    nextOpPreloaded ();                                 \
437
192k
}                                                       \
m3_compile.c:op_f64_Subtract_rs_f
Line
Count
Source
428
180k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
180k
{                                                       \
430
180k
    TYPE operand = slot (TYPE);                         \
431
180k
    TYPE * dest = slot_ptr (TYPE);                      \
432
180k
    d_m3PreloadNext ();                                 \
433
180k
    TYPE result;                                        \
434
180k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
180k
    * dest = result;  REG = result;                     \
436
180k
    nextOpPreloaded ();                                 \
437
180k
}                                                       \
m3_compile.c:op_f64_Multiply_rs_f
Line
Count
Source
428
169k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
169k
{                                                       \
430
169k
    TYPE operand = slot (TYPE);                         \
431
169k
    TYPE * dest = slot_ptr (TYPE);                      \
432
169k
    d_m3PreloadNext ();                                 \
433
169k
    TYPE result;                                        \
434
169k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
169k
    * dest = result;  REG = result;                     \
436
169k
    nextOpPreloaded ();                                 \
437
169k
}                                                       \
m3_compile.c:op_f64_Divide_rs_f
Line
Count
Source
428
3.24k
d_m3Op(TYPE##_##NAME##_rs_f)                            \
429
3.24k
{                                                       \
430
3.24k
    TYPE operand = slot (TYPE);                         \
431
3.24k
    TYPE * dest = slot_ptr (TYPE);                      \
432
3.24k
    d_m3PreloadNext ();                                 \
433
3.24k
    TYPE result;                                        \
434
3.24k
    OP((result), operand, ((TYPE) REG), ##__VA_ARGS__); \
435
3.24k
    * dest = result;  REG = result;                     \
436
3.24k
    nextOpPreloaded ();                                 \
437
3.24k
}                                                       \
438
5.68M
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
5.68M
{                                                       \
440
5.68M
    TYPE operand2 = slot (TYPE);                        \
441
5.68M
    TYPE operand1 = slot (TYPE);                        \
442
5.68M
    TYPE * dest = slot_ptr (TYPE);                      \
443
5.68M
    d_m3PreloadNext ();                                 \
444
5.68M
    TYPE result;                                        \
445
5.68M
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
5.68M
    * dest = result;  REG = result;                     \
447
5.68M
    nextOpPreloaded ();                                 \
448
5.68M
}
m3_compile.c:op_i32_Add_ss_f
Line
Count
Source
438
245k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
245k
{                                                       \
440
245k
    TYPE operand2 = slot (TYPE);                        \
441
245k
    TYPE operand1 = slot (TYPE);                        \
442
245k
    TYPE * dest = slot_ptr (TYPE);                      \
443
245k
    d_m3PreloadNext ();                                 \
444
245k
    TYPE result;                                        \
445
245k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
245k
    * dest = result;  REG = result;                     \
447
245k
    nextOpPreloaded ();                                 \
448
245k
}
m3_compile.c:op_i32_Subtract_ss_f
Line
Count
Source
438
200k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
200k
{                                                       \
440
200k
    TYPE operand2 = slot (TYPE);                        \
441
200k
    TYPE operand1 = slot (TYPE);                        \
442
200k
    TYPE * dest = slot_ptr (TYPE);                      \
443
200k
    d_m3PreloadNext ();                                 \
444
200k
    TYPE result;                                        \
445
200k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
200k
    * dest = result;  REG = result;                     \
447
200k
    nextOpPreloaded ();                                 \
448
200k
}
m3_compile.c:op_i32_Multiply_ss_f
Line
Count
Source
438
263k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
263k
{                                                       \
440
263k
    TYPE operand2 = slot (TYPE);                        \
441
263k
    TYPE operand1 = slot (TYPE);                        \
442
263k
    TYPE * dest = slot_ptr (TYPE);                      \
443
263k
    d_m3PreloadNext ();                                 \
444
263k
    TYPE result;                                        \
445
263k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
263k
    * dest = result;  REG = result;                     \
447
263k
    nextOpPreloaded ();                                 \
448
263k
}
m3_compile.c:op_u32_And_ss_f
Line
Count
Source
438
259k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
259k
{                                                       \
440
259k
    TYPE operand2 = slot (TYPE);                        \
441
259k
    TYPE operand1 = slot (TYPE);                        \
442
259k
    TYPE * dest = slot_ptr (TYPE);                      \
443
259k
    d_m3PreloadNext ();                                 \
444
259k
    TYPE result;                                        \
445
259k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
259k
    * dest = result;  REG = result;                     \
447
259k
    nextOpPreloaded ();                                 \
448
259k
}
m3_compile.c:op_u32_Or_ss_f
Line
Count
Source
438
272k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
272k
{                                                       \
440
272k
    TYPE operand2 = slot (TYPE);                        \
441
272k
    TYPE operand1 = slot (TYPE);                        \
442
272k
    TYPE * dest = slot_ptr (TYPE);                      \
443
272k
    d_m3PreloadNext ();                                 \
444
272k
    TYPE result;                                        \
445
272k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
272k
    * dest = result;  REG = result;                     \
447
272k
    nextOpPreloaded ();                                 \
448
272k
}
m3_compile.c:op_u32_Xor_ss_f
Line
Count
Source
438
357k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
357k
{                                                       \
440
357k
    TYPE operand2 = slot (TYPE);                        \
441
357k
    TYPE operand1 = slot (TYPE);                        \
442
357k
    TYPE * dest = slot_ptr (TYPE);                      \
443
357k
    d_m3PreloadNext ();                                 \
444
357k
    TYPE result;                                        \
445
357k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
357k
    * dest = result;  REG = result;                     \
447
357k
    nextOpPreloaded ();                                 \
448
357k
}
m3_compile.c:op_u32_ShiftLeft_ss_f
Line
Count
Source
438
251k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
251k
{                                                       \
440
251k
    TYPE operand2 = slot (TYPE);                        \
441
251k
    TYPE operand1 = slot (TYPE);                        \
442
251k
    TYPE * dest = slot_ptr (TYPE);                      \
443
251k
    d_m3PreloadNext ();                                 \
444
251k
    TYPE result;                                        \
445
251k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
251k
    * dest = result;  REG = result;                     \
447
251k
    nextOpPreloaded ();                                 \
448
251k
}
m3_compile.c:op_i32_ShiftRight_ss_f
Line
Count
Source
438
269k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
269k
{                                                       \
440
269k
    TYPE operand2 = slot (TYPE);                        \
441
269k
    TYPE operand1 = slot (TYPE);                        \
442
269k
    TYPE * dest = slot_ptr (TYPE);                      \
443
269k
    d_m3PreloadNext ();                                 \
444
269k
    TYPE result;                                        \
445
269k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
269k
    * dest = result;  REG = result;                     \
447
269k
    nextOpPreloaded ();                                 \
448
269k
}
m3_compile.c:op_u32_ShiftRight_ss_f
Line
Count
Source
438
235k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
235k
{                                                       \
440
235k
    TYPE operand2 = slot (TYPE);                        \
441
235k
    TYPE operand1 = slot (TYPE);                        \
442
235k
    TYPE * dest = slot_ptr (TYPE);                      \
443
235k
    d_m3PreloadNext ();                                 \
444
235k
    TYPE result;                                        \
445
235k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
235k
    * dest = result;  REG = result;                     \
447
235k
    nextOpPreloaded ();                                 \
448
235k
}
m3_compile.c:op_i64_Add_ss_f
Line
Count
Source
438
193k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
193k
{                                                       \
440
193k
    TYPE operand2 = slot (TYPE);                        \
441
193k
    TYPE operand1 = slot (TYPE);                        \
442
193k
    TYPE * dest = slot_ptr (TYPE);                      \
443
193k
    d_m3PreloadNext ();                                 \
444
193k
    TYPE result;                                        \
445
193k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
193k
    * dest = result;  REG = result;                     \
447
193k
    nextOpPreloaded ();                                 \
448
193k
}
m3_compile.c:op_i64_Subtract_ss_f
Line
Count
Source
438
461k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
461k
{                                                       \
440
461k
    TYPE operand2 = slot (TYPE);                        \
441
461k
    TYPE operand1 = slot (TYPE);                        \
442
461k
    TYPE * dest = slot_ptr (TYPE);                      \
443
461k
    d_m3PreloadNext ();                                 \
444
461k
    TYPE result;                                        \
445
461k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
461k
    * dest = result;  REG = result;                     \
447
461k
    nextOpPreloaded ();                                 \
448
461k
}
m3_compile.c:op_i64_Multiply_ss_f
Line
Count
Source
438
448k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
448k
{                                                       \
440
448k
    TYPE operand2 = slot (TYPE);                        \
441
448k
    TYPE operand1 = slot (TYPE);                        \
442
448k
    TYPE * dest = slot_ptr (TYPE);                      \
443
448k
    d_m3PreloadNext ();                                 \
444
448k
    TYPE result;                                        \
445
448k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
448k
    * dest = result;  REG = result;                     \
447
448k
    nextOpPreloaded ();                                 \
448
448k
}
m3_compile.c:op_u64_And_ss_f
Line
Count
Source
438
365k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
365k
{                                                       \
440
365k
    TYPE operand2 = slot (TYPE);                        \
441
365k
    TYPE operand1 = slot (TYPE);                        \
442
365k
    TYPE * dest = slot_ptr (TYPE);                      \
443
365k
    d_m3PreloadNext ();                                 \
444
365k
    TYPE result;                                        \
445
365k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
365k
    * dest = result;  REG = result;                     \
447
365k
    nextOpPreloaded ();                                 \
448
365k
}
m3_compile.c:op_u64_Or_ss_f
Line
Count
Source
438
188k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
188k
{                                                       \
440
188k
    TYPE operand2 = slot (TYPE);                        \
441
188k
    TYPE operand1 = slot (TYPE);                        \
442
188k
    TYPE * dest = slot_ptr (TYPE);                      \
443
188k
    d_m3PreloadNext ();                                 \
444
188k
    TYPE result;                                        \
445
188k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
188k
    * dest = result;  REG = result;                     \
447
188k
    nextOpPreloaded ();                                 \
448
188k
}
m3_compile.c:op_u64_Xor_ss_f
Line
Count
Source
438
139k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
139k
{                                                       \
440
139k
    TYPE operand2 = slot (TYPE);                        \
441
139k
    TYPE operand1 = slot (TYPE);                        \
442
139k
    TYPE * dest = slot_ptr (TYPE);                      \
443
139k
    d_m3PreloadNext ();                                 \
444
139k
    TYPE result;                                        \
445
139k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
139k
    * dest = result;  REG = result;                     \
447
139k
    nextOpPreloaded ();                                 \
448
139k
}
m3_compile.c:op_u64_ShiftLeft_ss_f
Line
Count
Source
438
60.8k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
60.8k
{                                                       \
440
60.8k
    TYPE operand2 = slot (TYPE);                        \
441
60.8k
    TYPE operand1 = slot (TYPE);                        \
442
60.8k
    TYPE * dest = slot_ptr (TYPE);                      \
443
60.8k
    d_m3PreloadNext ();                                 \
444
60.8k
    TYPE result;                                        \
445
60.8k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
60.8k
    * dest = result;  REG = result;                     \
447
60.8k
    nextOpPreloaded ();                                 \
448
60.8k
}
m3_compile.c:op_i64_ShiftRight_ss_f
Line
Count
Source
438
209k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
209k
{                                                       \
440
209k
    TYPE operand2 = slot (TYPE);                        \
441
209k
    TYPE operand1 = slot (TYPE);                        \
442
209k
    TYPE * dest = slot_ptr (TYPE);                      \
443
209k
    d_m3PreloadNext ();                                 \
444
209k
    TYPE result;                                        \
445
209k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
209k
    * dest = result;  REG = result;                     \
447
209k
    nextOpPreloaded ();                                 \
448
209k
}
m3_compile.c:op_u64_ShiftRight_ss_f
Line
Count
Source
438
317k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
317k
{                                                       \
440
317k
    TYPE operand2 = slot (TYPE);                        \
441
317k
    TYPE operand1 = slot (TYPE);                        \
442
317k
    TYPE * dest = slot_ptr (TYPE);                      \
443
317k
    d_m3PreloadNext ();                                 \
444
317k
    TYPE result;                                        \
445
317k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
317k
    * dest = result;  REG = result;                     \
447
317k
    nextOpPreloaded ();                                 \
448
317k
}
m3_compile.c:op_f32_Add_ss_f
Line
Count
Source
438
159k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
159k
{                                                       \
440
159k
    TYPE operand2 = slot (TYPE);                        \
441
159k
    TYPE operand1 = slot (TYPE);                        \
442
159k
    TYPE * dest = slot_ptr (TYPE);                      \
443
159k
    d_m3PreloadNext ();                                 \
444
159k
    TYPE result;                                        \
445
159k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
159k
    * dest = result;  REG = result;                     \
447
159k
    nextOpPreloaded ();                                 \
448
159k
}
m3_compile.c:op_f32_Subtract_ss_f
Line
Count
Source
438
155k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
155k
{                                                       \
440
155k
    TYPE operand2 = slot (TYPE);                        \
441
155k
    TYPE operand1 = slot (TYPE);                        \
442
155k
    TYPE * dest = slot_ptr (TYPE);                      \
443
155k
    d_m3PreloadNext ();                                 \
444
155k
    TYPE result;                                        \
445
155k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
155k
    * dest = result;  REG = result;                     \
447
155k
    nextOpPreloaded ();                                 \
448
155k
}
m3_compile.c:op_f32_Multiply_ss_f
Line
Count
Source
438
125k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
125k
{                                                       \
440
125k
    TYPE operand2 = slot (TYPE);                        \
441
125k
    TYPE operand1 = slot (TYPE);                        \
442
125k
    TYPE * dest = slot_ptr (TYPE);                      \
443
125k
    d_m3PreloadNext ();                                 \
444
125k
    TYPE result;                                        \
445
125k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
125k
    * dest = result;  REG = result;                     \
447
125k
    nextOpPreloaded ();                                 \
448
125k
}
m3_compile.c:op_f32_Divide_ss_f
Line
Count
Source
438
3.42k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
3.42k
{                                                       \
440
3.42k
    TYPE operand2 = slot (TYPE);                        \
441
3.42k
    TYPE operand1 = slot (TYPE);                        \
442
3.42k
    TYPE * dest = slot_ptr (TYPE);                      \
443
3.42k
    d_m3PreloadNext ();                                 \
444
3.42k
    TYPE result;                                        \
445
3.42k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
3.42k
    * dest = result;  REG = result;                     \
447
3.42k
    nextOpPreloaded ();                                 \
448
3.42k
}
m3_compile.c:op_f64_Add_ss_f
Line
Count
Source
438
159k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
159k
{                                                       \
440
159k
    TYPE operand2 = slot (TYPE);                        \
441
159k
    TYPE operand1 = slot (TYPE);                        \
442
159k
    TYPE * dest = slot_ptr (TYPE);                      \
443
159k
    d_m3PreloadNext ();                                 \
444
159k
    TYPE result;                                        \
445
159k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
159k
    * dest = result;  REG = result;                     \
447
159k
    nextOpPreloaded ();                                 \
448
159k
}
m3_compile.c:op_f64_Subtract_ss_f
Line
Count
Source
438
162k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
162k
{                                                       \
440
162k
    TYPE operand2 = slot (TYPE);                        \
441
162k
    TYPE operand1 = slot (TYPE);                        \
442
162k
    TYPE * dest = slot_ptr (TYPE);                      \
443
162k
    d_m3PreloadNext ();                                 \
444
162k
    TYPE result;                                        \
445
162k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
162k
    * dest = result;  REG = result;                     \
447
162k
    nextOpPreloaded ();                                 \
448
162k
}
m3_compile.c:op_f64_Multiply_ss_f
Line
Count
Source
438
168k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
168k
{                                                       \
440
168k
    TYPE operand2 = slot (TYPE);                        \
441
168k
    TYPE operand1 = slot (TYPE);                        \
442
168k
    TYPE * dest = slot_ptr (TYPE);                      \
443
168k
    d_m3PreloadNext ();                                 \
444
168k
    TYPE result;                                        \
445
168k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
168k
    * dest = result;  REG = result;                     \
447
168k
    nextOpPreloaded ();                                 \
448
168k
}
m3_compile.c:op_f64_Divide_ss_f
Line
Count
Source
438
7.01k
d_m3Op(TYPE##_##NAME##_ss_f)                            \
439
7.01k
{                                                       \
440
7.01k
    TYPE operand2 = slot (TYPE);                        \
441
7.01k
    TYPE operand1 = slot (TYPE);                        \
442
7.01k
    TYPE * dest = slot_ptr (TYPE);                      \
443
7.01k
    d_m3PreloadNext ();                                 \
444
7.01k
    TYPE result;                                        \
445
7.01k
    OP((result), operand1, operand2, ##__VA_ARGS__);    \
446
7.01k
    * dest = result;  REG = result;                     \
447
7.01k
    nextOpPreloaded ();                                 \
448
7.01k
}
449
450
#  define d_m3FoldOpMacro(REG, TYPE, NAME, OP, ...)     \
451
2.00M
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
2.00M
{                                                       \
453
2.00M
    TYPE operand = slot (TYPE);                         \
454
2.00M
    TYPE * dest = slot_ptr (TYPE);                      \
455
2.00M
    d_m3PreloadNext ();                                 \
456
2.00M
    TYPE result;                                        \
457
2.00M
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
2.00M
    * dest = result;  REG = result;                     \
459
2.00M
    nextOpPreloaded ();                                 \
460
2.00M
}                                                       \
m3_compile.c:op_i32_Subtract_sr_f
Line
Count
Source
451
170k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
170k
{                                                       \
453
170k
    TYPE operand = slot (TYPE);                         \
454
170k
    TYPE * dest = slot_ptr (TYPE);                      \
455
170k
    d_m3PreloadNext ();                                 \
456
170k
    TYPE result;                                        \
457
170k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
170k
    * dest = result;  REG = result;                     \
459
170k
    nextOpPreloaded ();                                 \
460
170k
}                                                       \
m3_compile.c:op_u32_ShiftLeft_sr_f
Line
Count
Source
451
255k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
255k
{                                                       \
453
255k
    TYPE operand = slot (TYPE);                         \
454
255k
    TYPE * dest = slot_ptr (TYPE);                      \
455
255k
    d_m3PreloadNext ();                                 \
456
255k
    TYPE result;                                        \
457
255k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
255k
    * dest = result;  REG = result;                     \
459
255k
    nextOpPreloaded ();                                 \
460
255k
}                                                       \
m3_compile.c:op_i32_ShiftRight_sr_f
Line
Count
Source
451
295k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
295k
{                                                       \
453
295k
    TYPE operand = slot (TYPE);                         \
454
295k
    TYPE * dest = slot_ptr (TYPE);                      \
455
295k
    d_m3PreloadNext ();                                 \
456
295k
    TYPE result;                                        \
457
295k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
295k
    * dest = result;  REG = result;                     \
459
295k
    nextOpPreloaded ();                                 \
460
295k
}                                                       \
m3_compile.c:op_u32_ShiftRight_sr_f
Line
Count
Source
451
370k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
370k
{                                                       \
453
370k
    TYPE operand = slot (TYPE);                         \
454
370k
    TYPE * dest = slot_ptr (TYPE);                      \
455
370k
    d_m3PreloadNext ();                                 \
456
370k
    TYPE result;                                        \
457
370k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
370k
    * dest = result;  REG = result;                     \
459
370k
    nextOpPreloaded ();                                 \
460
370k
}                                                       \
m3_compile.c:op_i64_Subtract_sr_f
Line
Count
Source
451
261k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
261k
{                                                       \
453
261k
    TYPE operand = slot (TYPE);                         \
454
261k
    TYPE * dest = slot_ptr (TYPE);                      \
455
261k
    d_m3PreloadNext ();                                 \
456
261k
    TYPE result;                                        \
457
261k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
261k
    * dest = result;  REG = result;                     \
459
261k
    nextOpPreloaded ();                                 \
460
261k
}                                                       \
m3_compile.c:op_u64_ShiftLeft_sr_f
Line
Count
Source
451
129k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
129k
{                                                       \
453
129k
    TYPE operand = slot (TYPE);                         \
454
129k
    TYPE * dest = slot_ptr (TYPE);                      \
455
129k
    d_m3PreloadNext ();                                 \
456
129k
    TYPE result;                                        \
457
129k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
129k
    * dest = result;  REG = result;                     \
459
129k
    nextOpPreloaded ();                                 \
460
129k
}                                                       \
m3_compile.c:op_i64_ShiftRight_sr_f
Line
Count
Source
451
201k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
201k
{                                                       \
453
201k
    TYPE operand = slot (TYPE);                         \
454
201k
    TYPE * dest = slot_ptr (TYPE);                      \
455
201k
    d_m3PreloadNext ();                                 \
456
201k
    TYPE result;                                        \
457
201k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
201k
    * dest = result;  REG = result;                     \
459
201k
    nextOpPreloaded ();                                 \
460
201k
}                                                       \
m3_compile.c:op_u64_ShiftRight_sr_f
Line
Count
Source
451
157k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
157k
{                                                       \
453
157k
    TYPE operand = slot (TYPE);                         \
454
157k
    TYPE * dest = slot_ptr (TYPE);                      \
455
157k
    d_m3PreloadNext ();                                 \
456
157k
    TYPE result;                                        \
457
157k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
157k
    * dest = result;  REG = result;                     \
459
157k
    nextOpPreloaded ();                                 \
460
157k
}                                                       \
m3_compile.c:op_f32_Subtract_sr_f
Line
Count
Source
451
92.0k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
92.0k
{                                                       \
453
92.0k
    TYPE operand = slot (TYPE);                         \
454
92.0k
    TYPE * dest = slot_ptr (TYPE);                      \
455
92.0k
    d_m3PreloadNext ();                                 \
456
92.0k
    TYPE result;                                        \
457
92.0k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
92.0k
    * dest = result;  REG = result;                     \
459
92.0k
    nextOpPreloaded ();                                 \
460
92.0k
}                                                       \
m3_compile.c:op_f32_Divide_sr_f
Line
Count
Source
451
1.46k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
1.46k
{                                                       \
453
1.46k
    TYPE operand = slot (TYPE);                         \
454
1.46k
    TYPE * dest = slot_ptr (TYPE);                      \
455
1.46k
    d_m3PreloadNext ();                                 \
456
1.46k
    TYPE result;                                        \
457
1.46k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
1.46k
    * dest = result;  REG = result;                     \
459
1.46k
    nextOpPreloaded ();                                 \
460
1.46k
}                                                       \
m3_compile.c:op_f64_Subtract_sr_f
Line
Count
Source
451
70.0k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
70.0k
{                                                       \
453
70.0k
    TYPE operand = slot (TYPE);                         \
454
70.0k
    TYPE * dest = slot_ptr (TYPE);                      \
455
70.0k
    d_m3PreloadNext ();                                 \
456
70.0k
    TYPE result;                                        \
457
70.0k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
70.0k
    * dest = result;  REG = result;                     \
459
70.0k
    nextOpPreloaded ();                                 \
460
70.0k
}                                                       \
m3_compile.c:op_f64_Divide_sr_f
Line
Count
Source
451
4.32k
d_m3Op(TYPE##_##NAME##_sr_f)                            \
452
4.32k
{                                                       \
453
4.32k
    TYPE operand = slot (TYPE);                         \
454
4.32k
    TYPE * dest = slot_ptr (TYPE);                      \
455
4.32k
    d_m3PreloadNext ();                                 \
456
4.32k
    TYPE result;                                        \
457
4.32k
    OP((result), ((TYPE) REG), operand, ##__VA_ARGS__); \
458
4.32k
    * dest = result;  REG = result;                     \
459
4.32k
    nextOpPreloaded ();                                 \
460
4.32k
}                                                       \
461
d_m3FoldCommutativeOpMacro(REG, TYPE, NAME, OP, ##__VA_ARGS__)
462
463
// A commutative operator has no _sr form in its variant table, so the fold set skips
464
// the _sr_f handler it could never be patched to.
465
#define d_m3FoldOp_i(TYPE, NAME, OP, ...)               d_m3FoldOpMacro             ( _r0, TYPE, NAME, OP, ##__VA_ARGS__)
466
#define d_m3FoldOp_f(TYPE, NAME, OP, ...)               d_m3FoldOpMacro             (_fp0, TYPE, NAME, OP, ##__VA_ARGS__)
467
#define d_m3FoldCommutativeOp_i(TYPE, NAME, OP, ...)    d_m3FoldCommutativeOpMacro  ( _r0, TYPE, NAME, OP, ##__VA_ARGS__)
468
#define d_m3FoldCommutativeOp_f(TYPE, NAME, OP, ...)    d_m3FoldCommutativeOpMacro  (_fp0, TYPE, NAME, OP, ##__VA_ARGS__)
469
470
376k
d_m3FoldCommutativeOp_i(i32, Add,          M3_FUNC, OP_ADD_32)
471
601k
d_m3FoldOp_i           (i32, Subtract,     M3_FUNC, OP_SUB_32)
472
610k
d_m3FoldCommutativeOp_i(i32, Multiply,     M3_FUNC, OP_MUL_32)
473
545k
d_m3FoldCommutativeOp_i(u32, And,          M3_OPER, &)
474
387k
d_m3FoldCommutativeOp_i(u32, Or,           M3_OPER, |)
475
630k
d_m3FoldCommutativeOp_i(u32, Xor,          M3_OPER, ^)
476
763k
d_m3FoldOp_i           (u32, ShiftLeft,    M3_FUNC, OP_SHL_32)
477
793k
d_m3FoldOp_i           (i32, ShiftRight,   M3_FUNC, OP_SHR_32)
478
778k
d_m3FoldOp_i           (u32, ShiftRight,   M3_FUNC, OP_SHR_32)
479
480
525k
d_m3FoldCommutativeOp_i(i64, Add,          M3_FUNC, OP_ADD_64)
481
965k
d_m3FoldOp_i           (i64, Subtract,     M3_FUNC, OP_SUB_64)
482
794k
d_m3FoldCommutativeOp_i(i64, Multiply,     M3_FUNC, OP_MUL_64)
483
690k
d_m3FoldCommutativeOp_i(u64, And,          M3_OPER, &)
484
469k
d_m3FoldCommutativeOp_i(u64, Or,           M3_OPER, |)
485
248k
d_m3FoldCommutativeOp_i(u64, Xor,          M3_OPER, ^)
486
339k
d_m3FoldOp_i           (u64, ShiftLeft,    M3_FUNC, OP_SHL_64)
487
507k
d_m3FoldOp_i           (i64, ShiftRight,   M3_FUNC, OP_SHR_64)
488
622k
d_m3FoldOp_i           (u64, ShiftRight,   M3_FUNC, OP_SHR_64)
489
490
#  if d_m3HasFloat
491
// Without these a float result round-trips through _fp0 and a separate SetSlot, which
492
// on float-heavy code is about one dispatch in five.
493
255k
d_m3FoldCommutativeOp_f(f32, Add,          M3_OPER_A, +, canon_nan_f32)
494
362k
d_m3FoldOp_f           (f32, Subtract,     M3_OPER_A, -, canon_nan_f32)
495
334k
d_m3FoldCommutativeOp_f(f32, Multiply,     M3_OPER_A, *, canon_nan_f32)
496
7.77k
d_m3FoldOp_f           (f32, Divide,       M3_OPER_A, /, canon_nan_f32)
497
351k
d_m3FoldCommutativeOp_f(f64, Add,          M3_OPER_A, +, canon_nan_f64)
498
413k
d_m3FoldOp_f           (f64, Subtract,     M3_OPER_A, -, canon_nan_f64)
499
338k
d_m3FoldCommutativeOp_f(f64, Multiply,     M3_OPER_A, *, canon_nan_f64)
500
14.5k
d_m3FoldOp_f           (f64, Divide,       M3_OPER_A, /, canon_nan_f64)
501
#endif
502
503
#endif // d_m3FoldSetLocal
504
505
#if d_m3HasFloat
506
d_m3CommutativeArithOp_f(f32, Add,         +)      d_m3CommutativeArithOp_f(f64, Add,         +)
507
d_m3CommutativeArithOp_f(f32, Multiply,    *)      d_m3CommutativeArithOp_f(f64, Multiply,    *)
508
d_m3ArithOp_f(f32, Subtract,               -)      d_m3ArithOp_f(f64, Subtract,               -)
509
d_m3ArithOp_f(f32, Divide,                 /)      d_m3ArithOp_f(f64, Divide,                 /)
510
#endif
511
512
d_m3OpFunc_i(u32, Rotl, rotl32)
513
d_m3OpFunc_i(u32, Rotr, rotr32)
514
d_m3OpFunc_i(u64, Rotl, rotl64)
515
d_m3OpFunc_i(u64, Rotr, rotr64)
516
517
42.9k
d_m3OpMacro_i(u32, Divide, OP_DIV_U);
518
46.6k
d_m3OpMacro_i(i32, Divide, OP_DIV_S, INT32_MIN);
519
38.0k
d_m3OpMacro_i(u64, Divide, OP_DIV_U);
520
61.4k
d_m3OpMacro_i(i64, Divide, OP_DIV_S, INT64_MIN);
521
522
41.8k
d_m3OpMacro_i(u32, Remainder, OP_REM_U);
523
50.8k
d_m3OpMacro_i(i32, Remainder, OP_REM_S, INT32_MIN);
524
45.9k
d_m3OpMacro_i(u64, Remainder, OP_REM_U);
525
55.2k
d_m3OpMacro_i(i64, Remainder, OP_REM_S, INT64_MIN);
526
527
#if d_m3HasFloat
528
d_m3ArithOpFunc_f(f32, Min, min_f32);
529
d_m3ArithOpFunc_f(f32, Max, max_f32);
530
d_m3ArithOpFunc_f(f64, Min, min_f64);
531
d_m3ArithOpFunc_f(f64, Max, max_f64);
532
533
// copysign is defined bitwise and keeps its operand's payload - see canon_nan_f32
534
d_m3OpFunc_f(f32, CopySign, copysignf);
535
d_m3OpFunc_f(f64, CopySign, copysign);
536
#endif
537
538
// Unary operations
539
// Note: This macro follows the principle of d_m3OpMacro
540
541
#define d_m3UnaryMacro(RES, REG, TYPE, NAME, OP, ...)   \
542
41.3M
d_m3Op(TYPE##_##NAME##_r)                           \
543
41.3M
{                                                   \
544
41.3M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
41.3M
    nextOp ();                                      \
546
41.3M
}                                                   \
m3_compile.c:op_i64_EqualToZero_r
Line
Count
Source
542
1.31M
d_m3Op(TYPE##_##NAME##_r)                           \
543
1.31M
{                                                   \
544
1.31M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
1.31M
    nextOp ();                                      \
546
1.31M
}                                                   \
m3_compile.c:op_i32_EqualToZero_r
Line
Count
Source
542
4.18M
d_m3Op(TYPE##_##NAME##_r)                           \
543
4.18M
{                                                   \
544
4.18M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
4.18M
    nextOp ();                                      \
546
4.18M
}                                                   \
m3_compile.c:op_u32_Clz_r
Line
Count
Source
542
3.11M
d_m3Op(TYPE##_##NAME##_r)                           \
543
3.11M
{                                                   \
544
3.11M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
3.11M
    nextOp ();                                      \
546
3.11M
}                                                   \
m3_compile.c:op_u32_Ctz_r
Line
Count
Source
542
2.20M
d_m3Op(TYPE##_##NAME##_r)                           \
543
2.20M
{                                                   \
544
2.20M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
2.20M
    nextOp ();                                      \
546
2.20M
}                                                   \
m3_compile.c:op_u32_Popcnt_r
Line
Count
Source
542
3.22M
d_m3Op(TYPE##_##NAME##_r)                           \
543
3.22M
{                                                   \
544
3.22M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
3.22M
    nextOp ();                                      \
546
3.22M
}                                                   \
m3_compile.c:op_u64_Clz_r
Line
Count
Source
542
2.76M
d_m3Op(TYPE##_##NAME##_r)                           \
543
2.76M
{                                                   \
544
2.76M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
2.76M
    nextOp ();                                      \
546
2.76M
}                                                   \
m3_compile.c:op_u64_Ctz_r
Line
Count
Source
542
2.32M
d_m3Op(TYPE##_##NAME##_r)                           \
543
2.32M
{                                                   \
544
2.32M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
2.32M
    nextOp ();                                      \
546
2.32M
}                                                   \
m3_compile.c:op_u64_Popcnt_r
Line
Count
Source
542
1.66M
d_m3Op(TYPE##_##NAME##_r)                           \
543
1.66M
{                                                   \
544
1.66M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
1.66M
    nextOp ();                                      \
546
1.66M
}                                                   \
m3_compile.c:op_f32_Abs_r
Line
Count
Source
542
974k
d_m3Op(TYPE##_##NAME##_r)                           \
543
974k
{                                                   \
544
974k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
974k
    nextOp ();                                      \
546
974k
}                                                   \
m3_compile.c:op_f32_Negate_r
Line
Count
Source
542
1.09M
d_m3Op(TYPE##_##NAME##_r)                           \
543
1.09M
{                                                   \
544
1.09M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
1.09M
    nextOp ();                                      \
546
1.09M
}                                                   \
m3_compile.c:op_f32_Ceil_r
Line
Count
Source
542
1.39M
d_m3Op(TYPE##_##NAME##_r)                           \
543
1.39M
{                                                   \
544
1.39M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
1.39M
    nextOp ();                                      \
546
1.39M
}                                                   \
m3_compile.c:op_f32_Floor_r
Line
Count
Source
542
1.13M
d_m3Op(TYPE##_##NAME##_r)                           \
543
1.13M
{                                                   \
544
1.13M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
1.13M
    nextOp ();                                      \
546
1.13M
}                                                   \
m3_compile.c:op_f32_Trunc_r
Line
Count
Source
542
1.49M
d_m3Op(TYPE##_##NAME##_r)                           \
543
1.49M
{                                                   \
544
1.49M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
1.49M
    nextOp ();                                      \
546
1.49M
}                                                   \
m3_compile.c:op_f32_Nearest_r
Line
Count
Source
542
573k
d_m3Op(TYPE##_##NAME##_r)                           \
543
573k
{                                                   \
544
573k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
573k
    nextOp ();                                      \
546
573k
}                                                   \
m3_compile.c:op_f32_Sqrt_r
Line
Count
Source
542
13.7k
d_m3Op(TYPE##_##NAME##_r)                           \
543
13.7k
{                                                   \
544
13.7k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
13.7k
    nextOp ();                                      \
546
13.7k
}                                                   \
m3_compile.c:op_f64_Abs_r
Line
Count
Source
542
396k
d_m3Op(TYPE##_##NAME##_r)                           \
543
396k
{                                                   \
544
396k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
396k
    nextOp ();                                      \
546
396k
}                                                   \
m3_compile.c:op_f64_Negate_r
Line
Count
Source
542
775k
d_m3Op(TYPE##_##NAME##_r)                           \
543
775k
{                                                   \
544
775k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
775k
    nextOp ();                                      \
546
775k
}                                                   \
m3_compile.c:op_f64_Ceil_r
Line
Count
Source
542
650k
d_m3Op(TYPE##_##NAME##_r)                           \
543
650k
{                                                   \
544
650k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
650k
    nextOp ();                                      \
546
650k
}                                                   \
m3_compile.c:op_f64_Floor_r
Line
Count
Source
542
746k
d_m3Op(TYPE##_##NAME##_r)                           \
543
746k
{                                                   \
544
746k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
746k
    nextOp ();                                      \
546
746k
}                                                   \
m3_compile.c:op_f64_Trunc_r
Line
Count
Source
542
958k
d_m3Op(TYPE##_##NAME##_r)                           \
543
958k
{                                                   \
544
958k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
958k
    nextOp ();                                      \
546
958k
}                                                   \
m3_compile.c:op_f64_Nearest_r
Line
Count
Source
542
544k
d_m3Op(TYPE##_##NAME##_r)                           \
543
544k
{                                                   \
544
544k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
544k
    nextOp ();                                      \
546
544k
}                                                   \
m3_compile.c:op_f64_Sqrt_r
Line
Count
Source
542
12.4k
d_m3Op(TYPE##_##NAME##_r)                           \
543
12.4k
{                                                   \
544
12.4k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
12.4k
    nextOp ();                                      \
546
12.4k
}                                                   \
m3_compile.c:op_i32_Extend8_s_r
Line
Count
Source
542
2.42M
d_m3Op(TYPE##_##NAME##_r)                           \
543
2.42M
{                                                   \
544
2.42M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
2.42M
    nextOp ();                                      \
546
2.42M
}                                                   \
m3_compile.c:op_i32_Extend16_s_r
Line
Count
Source
542
3.77M
d_m3Op(TYPE##_##NAME##_r)                           \
543
3.77M
{                                                   \
544
3.77M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
3.77M
    nextOp ();                                      \
546
3.77M
}                                                   \
m3_compile.c:op_i64_Extend8_s_r
Line
Count
Source
542
1.25M
d_m3Op(TYPE##_##NAME##_r)                           \
543
1.25M
{                                                   \
544
1.25M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
1.25M
    nextOp ();                                      \
546
1.25M
}                                                   \
m3_compile.c:op_i64_Extend16_s_r
Line
Count
Source
542
1.44M
d_m3Op(TYPE##_##NAME##_r)                           \
543
1.44M
{                                                   \
544
1.44M
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
1.44M
    nextOp ();                                      \
546
1.44M
}                                                   \
m3_compile.c:op_i64_Extend32_s_r
Line
Count
Source
542
921k
d_m3Op(TYPE##_##NAME##_r)                           \
543
921k
{                                                   \
544
921k
    OP((RES), (TYPE) REG, ##__VA_ARGS__);           \
545
921k
    nextOp ();                                      \
546
921k
}                                                   \
547
99.2M
d_m3Op(TYPE##_##NAME##_s)                           \
548
99.2M
{                                                   \
549
99.2M
    TYPE operand = slot (TYPE);                     \
550
99.2M
    OP((RES), operand, ##__VA_ARGS__);              \
551
99.2M
    nextOp ();                                      \
552
99.2M
}
m3_compile.c:op_i64_EqualToZero_s
Line
Count
Source
547
2.76M
d_m3Op(TYPE##_##NAME##_s)                           \
548
2.76M
{                                                   \
549
2.76M
    TYPE operand = slot (TYPE);                     \
550
2.76M
    OP((RES), operand, ##__VA_ARGS__);              \
551
2.76M
    nextOp ();                                      \
552
2.76M
}
m3_compile.c:op_i32_EqualToZero_s
Line
Count
Source
547
10.1M
d_m3Op(TYPE##_##NAME##_s)                           \
548
10.1M
{                                                   \
549
10.1M
    TYPE operand = slot (TYPE);                     \
550
10.1M
    OP((RES), operand, ##__VA_ARGS__);              \
551
10.1M
    nextOp ();                                      \
552
10.1M
}
m3_compile.c:op_u32_Clz_s
Line
Count
Source
547
4.42M
d_m3Op(TYPE##_##NAME##_s)                           \
548
4.42M
{                                                   \
549
4.42M
    TYPE operand = slot (TYPE);                     \
550
4.42M
    OP((RES), operand, ##__VA_ARGS__);              \
551
4.42M
    nextOp ();                                      \
552
4.42M
}
m3_compile.c:op_u32_Ctz_s
Line
Count
Source
547
4.74M
d_m3Op(TYPE##_##NAME##_s)                           \
548
4.74M
{                                                   \
549
4.74M
    TYPE operand = slot (TYPE);                     \
550
4.74M
    OP((RES), operand, ##__VA_ARGS__);              \
551
4.74M
    nextOp ();                                      \
552
4.74M
}
m3_compile.c:op_u32_Popcnt_s
Line
Count
Source
547
5.61M
d_m3Op(TYPE##_##NAME##_s)                           \
548
5.61M
{                                                   \
549
5.61M
    TYPE operand = slot (TYPE);                     \
550
5.61M
    OP((RES), operand, ##__VA_ARGS__);              \
551
5.61M
    nextOp ();                                      \
552
5.61M
}
m3_compile.c:op_u64_Clz_s
Line
Count
Source
547
5.38M
d_m3Op(TYPE##_##NAME##_s)                           \
548
5.38M
{                                                   \
549
5.38M
    TYPE operand = slot (TYPE);                     \
550
5.38M
    OP((RES), operand, ##__VA_ARGS__);              \
551
5.38M
    nextOp ();                                      \
552
5.38M
}
m3_compile.c:op_u64_Ctz_s
Line
Count
Source
547
8.73M
d_m3Op(TYPE##_##NAME##_s)                           \
548
8.73M
{                                                   \
549
8.73M
    TYPE operand = slot (TYPE);                     \
550
8.73M
    OP((RES), operand, ##__VA_ARGS__);              \
551
8.73M
    nextOp ();                                      \
552
8.73M
}
m3_compile.c:op_u64_Popcnt_s
Line
Count
Source
547
5.04M
d_m3Op(TYPE##_##NAME##_s)                           \
548
5.04M
{                                                   \
549
5.04M
    TYPE operand = slot (TYPE);                     \
550
5.04M
    OP((RES), operand, ##__VA_ARGS__);              \
551
5.04M
    nextOp ();                                      \
552
5.04M
}
m3_compile.c:op_f32_Abs_s
Line
Count
Source
547
2.92M
d_m3Op(TYPE##_##NAME##_s)                           \
548
2.92M
{                                                   \
549
2.92M
    TYPE operand = slot (TYPE);                     \
550
2.92M
    OP((RES), operand, ##__VA_ARGS__);              \
551
2.92M
    nextOp ();                                      \
552
2.92M
}
m3_compile.c:op_f32_Negate_s
Line
Count
Source
547
2.34M
d_m3Op(TYPE##_##NAME##_s)                           \
548
2.34M
{                                                   \
549
2.34M
    TYPE operand = slot (TYPE);                     \
550
2.34M
    OP((RES), operand, ##__VA_ARGS__);              \
551
2.34M
    nextOp ();                                      \
552
2.34M
}
m3_compile.c:op_f32_Ceil_s
Line
Count
Source
547
2.56M
d_m3Op(TYPE##_##NAME##_s)                           \
548
2.56M
{                                                   \
549
2.56M
    TYPE operand = slot (TYPE);                     \
550
2.56M
    OP((RES), operand, ##__VA_ARGS__);              \
551
2.56M
    nextOp ();                                      \
552
2.56M
}
m3_compile.c:op_f32_Floor_s
Line
Count
Source
547
3.11M
d_m3Op(TYPE##_##NAME##_s)                           \
548
3.11M
{                                                   \
549
3.11M
    TYPE operand = slot (TYPE);                     \
550
3.11M
    OP((RES), operand, ##__VA_ARGS__);              \
551
3.11M
    nextOp ();                                      \
552
3.11M
}
m3_compile.c:op_f32_Trunc_s
Line
Count
Source
547
3.25M
d_m3Op(TYPE##_##NAME##_s)                           \
548
3.25M
{                                                   \
549
3.25M
    TYPE operand = slot (TYPE);                     \
550
3.25M
    OP((RES), operand, ##__VA_ARGS__);              \
551
3.25M
    nextOp ();                                      \
552
3.25M
}
m3_compile.c:op_f32_Nearest_s
Line
Count
Source
547
1.64M
d_m3Op(TYPE##_##NAME##_s)                           \
548
1.64M
{                                                   \
549
1.64M
    TYPE operand = slot (TYPE);                     \
550
1.64M
    OP((RES), operand, ##__VA_ARGS__);              \
551
1.64M
    nextOp ();                                      \
552
1.64M
}
m3_compile.c:op_f32_Sqrt_s
Line
Count
Source
547
16.0k
d_m3Op(TYPE##_##NAME##_s)                           \
548
16.0k
{                                                   \
549
16.0k
    TYPE operand = slot (TYPE);                     \
550
16.0k
    OP((RES), operand, ##__VA_ARGS__);              \
551
16.0k
    nextOp ();                                      \
552
16.0k
}
m3_compile.c:op_f64_Abs_s
Line
Count
Source
547
1.69M
d_m3Op(TYPE##_##NAME##_s)                           \
548
1.69M
{                                                   \
549
1.69M
    TYPE operand = slot (TYPE);                     \
550
1.69M
    OP((RES), operand, ##__VA_ARGS__);              \
551
1.69M
    nextOp ();                                      \
552
1.69M
}
m3_compile.c:op_f64_Negate_s
Line
Count
Source
547
1.92M
d_m3Op(TYPE##_##NAME##_s)                           \
548
1.92M
{                                                   \
549
1.92M
    TYPE operand = slot (TYPE);                     \
550
1.92M
    OP((RES), operand, ##__VA_ARGS__);              \
551
1.92M
    nextOp ();                                      \
552
1.92M
}
m3_compile.c:op_f64_Ceil_s
Line
Count
Source
547
1.87M
d_m3Op(TYPE##_##NAME##_s)                           \
548
1.87M
{                                                   \
549
1.87M
    TYPE operand = slot (TYPE);                     \
550
1.87M
    OP((RES), operand, ##__VA_ARGS__);              \
551
1.87M
    nextOp ();                                      \
552
1.87M
}
m3_compile.c:op_f64_Floor_s
Line
Count
Source
547
1.53M
d_m3Op(TYPE##_##NAME##_s)                           \
548
1.53M
{                                                   \
549
1.53M
    TYPE operand = slot (TYPE);                     \
550
1.53M
    OP((RES), operand, ##__VA_ARGS__);              \
551
1.53M
    nextOp ();                                      \
552
1.53M
}
m3_compile.c:op_f64_Trunc_s
Line
Count
Source
547
1.36M
d_m3Op(TYPE##_##NAME##_s)                           \
548
1.36M
{                                                   \
549
1.36M
    TYPE operand = slot (TYPE);                     \
550
1.36M
    OP((RES), operand, ##__VA_ARGS__);              \
551
1.36M
    nextOp ();                                      \
552
1.36M
}
m3_compile.c:op_f64_Nearest_s
Line
Count
Source
547
1.53M
d_m3Op(TYPE##_##NAME##_s)                           \
548
1.53M
{                                                   \
549
1.53M
    TYPE operand = slot (TYPE);                     \
550
1.53M
    OP((RES), operand, ##__VA_ARGS__);              \
551
1.53M
    nextOp ();                                      \
552
1.53M
}
m3_compile.c:op_f64_Sqrt_s
Line
Count
Source
547
24.9k
d_m3Op(TYPE##_##NAME##_s)                           \
548
24.9k
{                                                   \
549
24.9k
    TYPE operand = slot (TYPE);                     \
550
24.9k
    OP((RES), operand, ##__VA_ARGS__);              \
551
24.9k
    nextOp ();                                      \
552
24.9k
}
m3_compile.c:op_i32_Extend8_s_s
Line
Count
Source
547
4.37M
d_m3Op(TYPE##_##NAME##_s)                           \
548
4.37M
{                                                   \
549
4.37M
    TYPE operand = slot (TYPE);                     \
550
4.37M
    OP((RES), operand, ##__VA_ARGS__);              \
551
4.37M
    nextOp ();                                      \
552
4.37M
}
m3_compile.c:op_i32_Extend16_s_s
Line
Count
Source
547
9.37M
d_m3Op(TYPE##_##NAME##_s)                           \
548
9.37M
{                                                   \
549
9.37M
    TYPE operand = slot (TYPE);                     \
550
9.37M
    OP((RES), operand, ##__VA_ARGS__);              \
551
9.37M
    nextOp ();                                      \
552
9.37M
}
m3_compile.c:op_i64_Extend8_s_s
Line
Count
Source
547
5.53M
d_m3Op(TYPE##_##NAME##_s)                           \
548
5.53M
{                                                   \
549
5.53M
    TYPE operand = slot (TYPE);                     \
550
5.53M
    OP((RES), operand, ##__VA_ARGS__);              \
551
5.53M
    nextOp ();                                      \
552
5.53M
}
m3_compile.c:op_i64_Extend16_s_s
Line
Count
Source
547
3.48M
d_m3Op(TYPE##_##NAME##_s)                           \
548
3.48M
{                                                   \
549
3.48M
    TYPE operand = slot (TYPE);                     \
550
3.48M
    OP((RES), operand, ##__VA_ARGS__);              \
551
3.48M
    nextOp ();                                      \
552
3.48M
}
m3_compile.c:op_i64_Extend32_s_s
Line
Count
Source
547
3.76M
d_m3Op(TYPE##_##NAME##_s)                           \
548
3.76M
{                                                   \
549
3.76M
    TYPE operand = slot (TYPE);                     \
550
3.76M
    OP((RES), operand, ##__VA_ARGS__);              \
551
3.76M
    nextOp ();                                      \
552
3.76M
}
553
554
116M
#define M3_UNARY(RES, X, OP) (RES) = OP(X)
555
24.4M
#define M3_UNARY_A(RES, X, OP, CANON) (RES) = CANON(OP(X))
556
557
104M
#define d_m3UnaryOp_i(TYPE, NAME, OPERATION)        d_m3UnaryMacro( _r0,  _r0, TYPE, NAME, M3_UNARY, OPERATION)
558
12.1M
#define d_m3UnaryOp_f(TYPE, NAME, OPERATION)        d_m3UnaryMacro(_fp0, _fp0, TYPE, NAME, M3_UNARY, OPERATION)
559
24.4M
#define d_m3UnaryArithOp_f(TYPE, NAME, OPERATION)   d_m3UnaryMacro(_fp0, _fp0, TYPE, NAME, M3_UNARY_A, OPERATION, canon_nan_##TYPE)
560
561
#if d_m3HasFloat
562
// abs and neg are defined bitwise and keep their operand's payload - see canon_nan_f32
563
d_m3UnaryOp_f(f32, Abs,             fabsf);    d_m3UnaryOp_f(f64, Abs,             fabs);
564
d_m3UnaryArithOp_f(f32, Ceil,       ceilf);    d_m3UnaryArithOp_f(f64, Ceil,       ceil);
565
d_m3UnaryArithOp_f(f32, Floor,      floorf);   d_m3UnaryArithOp_f(f64, Floor,      floor);
566
d_m3UnaryArithOp_f(f32, Trunc,      truncf);   d_m3UnaryArithOp_f(f64, Trunc,      trunc);
567
d_m3UnaryArithOp_f(f32, Sqrt,       sqrtf);    d_m3UnaryArithOp_f(f64, Sqrt,       sqrt);
568
d_m3UnaryArithOp_f(f32, Nearest,    rintf);    d_m3UnaryArithOp_f(f64, Nearest,    rint);
569
#  if defined(M3_COMPILER_TCC)
570
d_m3UnaryOp_f(f32, Negate,     m3_negf);       d_m3UnaryOp_f(f64, Negate,     m3_neg);
571
#  else
572
d_m3UnaryOp_f(f32, Negate,     -);             d_m3UnaryOp_f(f64, Negate,     -);
573
#  endif
574
#endif
575
576
18.4M
#define OP_EQZ(x) ((x) == 0)
577
578
14.3M
d_m3UnaryOp_i(i32, EqualToZero, OP_EQZ)
579
4.08M
d_m3UnaryOp_i(i64, EqualToZero, OP_EQZ)
580
581
// clz(0), ctz(0) results are undefined for rest platforms, fix it
582
#if (defined(__i386__) || defined(__x86_64__)) && !(defined(__AVX2__) || (defined(__ABM__) && defined(__BMI__)))
583
#define OP_CLZ_32(x) (M3_UNLIKELY((x) == 0) ? 32 : __builtin_clz(x))
584
#define OP_CTZ_32(x) (M3_UNLIKELY((x) == 0) ? 32 : __builtin_ctz(x))
585
// for 64-bit instructions branchless approach more preferable
586
#define OP_CLZ_64(x) (__builtin_clzll((x) | (1ULL <<  0)) + OP_EQZ(x))
587
#define OP_CTZ_64(x) (__builtin_ctzll((x) | (1ULL << 63)) + OP_EQZ(x))
588
#elif defined(__ppc__) || defined(__ppc64__)
589
// PowerPC is defined for __builtin_clz(0) and __builtin_ctz(0).
590
// See (https://github.com/aquynh/capstone/blob/master/MathExtras.h#L99)
591
#define OP_CLZ_32(x) __builtin_clz(x)
592
#define OP_CTZ_32(x) __builtin_ctz(x)
593
#define OP_CLZ_64(x) __builtin_clzll(x)
594
#define OP_CTZ_64(x) __builtin_ctzll(x)
595
#else
596
7.54M
#define OP_CLZ_32(x) (M3_UNLIKELY((x) == 0) ? 32 : __builtin_clz(x))
597
6.94M
#define OP_CTZ_32(x) (M3_UNLIKELY((x) == 0) ? 32 : __builtin_ctz(x))
598
8.14M
#define OP_CLZ_64(x) (M3_UNLIKELY((x) == 0) ? 64 : __builtin_clzll(x))
599
11.0M
#define OP_CTZ_64(x) (M3_UNLIKELY((x) == 0) ? 64 : __builtin_ctzll(x))
600
#endif
601
602
7.54M
d_m3UnaryOp_i(u32, Clz, OP_CLZ_32)
603
8.14M
d_m3UnaryOp_i(u64, Clz, OP_CLZ_64)
604
605
6.94M
d_m3UnaryOp_i(u32, Ctz, OP_CTZ_32)
606
11.0M
d_m3UnaryOp_i(u64, Ctz, OP_CTZ_64)
607
608
d_m3UnaryOp_i(u32, Popcnt, __builtin_popcount)
609
d_m3UnaryOp_i(u64, Popcnt, __builtin_popcountll)
610
611
2.33M
#define OP_WRAP_I64(X) ((X) & 0x00000000ffffffff)
612
613
d_m3Op(i32_Wrap_i64_r)
614
1.03M
{
615
1.03M
    _r0 = OP_WRAP_I64((i64)_r0);
616
1.03M
    nextOp();
617
1.03M
}
618
619
d_m3Op(i32_Wrap_i64_s)
620
1.30M
{
621
1.30M
    i64 operand = slot(i64);
622
1.30M
    _r0 = OP_WRAP_I64(operand);
623
1.30M
    nextOp();
624
1.30M
}
625
626
// Integer sign extension operations
627
6.79M
#define OP_EXTEND8_S_I32(X)  ((int32_t)(int8_t)(X))
628
13.1M
#define OP_EXTEND16_S_I32(X) ((int32_t)(int16_t)(X))
629
6.79M
#define OP_EXTEND8_S_I64(X)  ((int64_t)(int8_t)(X))
630
4.93M
#define OP_EXTEND16_S_I64(X) ((int64_t)(int16_t)(X))
631
4.68M
#define OP_EXTEND32_S_I64(X) ((int64_t)(int32_t)(X))
632
633
6.79M
d_m3UnaryOp_i(i32, Extend8_s,  OP_EXTEND8_S_I32)
634
13.1M
d_m3UnaryOp_i(i32, Extend16_s, OP_EXTEND16_S_I32)
635
6.79M
d_m3UnaryOp_i(i64, Extend8_s,  OP_EXTEND8_S_I64)
636
4.93M
d_m3UnaryOp_i(i64, Extend16_s, OP_EXTEND16_S_I64)
637
4.68M
d_m3UnaryOp_i(i64, Extend32_s, OP_EXTEND32_S_I64)
638
639
#if d_m3HasWideArithmetic
640
641
// Wide arithmetic. Every operand is in a slot, the top of the stack first, and
642
// the last immediate is the slot the low half of the result goes to; the high
643
// half goes to _r0. That slot may be one an operand was just read from, so it is
644
// only written once all of them are.
645
d_m3Op(i64_Add128)
646
547k
{
647
547k
    u64  rhsHigh = slot (u64);
648
547k
    u64  rhsLow  = slot (u64);
649
547k
    u64  lhsHigh = slot (u64);
650
547k
    u64  lhsLow  = slot (u64);
651
547k
    u64* low     = slot_ptr (u64);
652
547k
    d_m3PreloadNext();
653
654
547k
    u64 sum = lhsLow + rhsLow;
655
656
547k
    *low = sum;
657
547k
    _r0  = (i64) (lhsHigh + rhsHigh + (sum < lhsLow));
658
659
547k
    nextOpPreloaded();
660
547k
}
661
662
d_m3Op(i64_Sub128)
663
1.63M
{
664
1.63M
    u64  rhsHigh = slot (u64);
665
1.63M
    u64  rhsLow  = slot (u64);
666
1.63M
    u64  lhsHigh = slot (u64);
667
1.63M
    u64  lhsLow  = slot (u64);
668
1.63M
    u64* low     = slot_ptr (u64);
669
1.63M
    d_m3PreloadNext();
670
671
1.63M
    *low = lhsLow - rhsLow;
672
1.63M
    _r0  = (i64) (lhsHigh - rhsHigh - (lhsLow < rhsLow));
673
674
1.63M
    nextOpPreloaded();
675
1.63M
}
676
677
d_m3Op(i64_MultiplyWide)
678
1.67M
{
679
1.67M
    i64  b   = slot (i64);
680
1.67M
    i64  a   = slot (i64);
681
1.67M
    u64* low = slot_ptr (u64);
682
1.67M
    d_m3PreloadNext();
683
684
1.67M
    u64 high;
685
1.67M
    *low = mul_wide_i64 (a, b, &high);
686
1.67M
    _r0  = (i64) high;
687
688
1.67M
    nextOpPreloaded();
689
1.67M
}
690
691
d_m3Op(u64_MultiplyWide)
692
644k
{
693
644k
    u64  b   = slot (u64);
694
644k
    u64  a   = slot (u64);
695
644k
    u64* low = slot_ptr (u64);
696
644k
    d_m3PreloadNext();
697
698
644k
    u64 high;
699
644k
    *low = mul_wide_u64 (a, b, &high);
700
644k
    _r0  = (i64) high;
701
702
644k
    nextOpPreloaded();
703
644k
}
704
705
#endif // d_m3HasWideArithmetic
706
707
#define d_m3TruncMacro(DEST, SRC, TYPE, NAME, FROM, OP, ...)   \
708
14.3M
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
14.3M
{                                                   \
710
14.3M
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
14.3M
    nextOp ();                                      \
712
5.39M
}                                                   \
m3_compile.c:op_i32_Trunc_f32_r_r
Line
Count
Source
708
637k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
637k
{                                                   \
710
637k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
637k
    nextOp ();                                      \
712
637k
}                                                   \
m3_compile.c:op_u32_Trunc_f32_r_r
Line
Count
Source
708
805k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
805k
{                                                   \
710
805k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
805k
    nextOp ();                                      \
712
805k
}                                                   \
m3_compile.c:op_i32_Trunc_f64_r_r
Line
Count
Source
708
713k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
713k
{                                                   \
710
713k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
713k
    nextOp ();                                      \
712
713k
}                                                   \
m3_compile.c:op_u32_Trunc_f64_r_r
Line
Count
Source
708
874k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
874k
{                                                   \
710
874k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
874k
    nextOp ();                                      \
712
874k
}                                                   \
m3_compile.c:op_i64_Trunc_f32_r_r
Line
Count
Source
708
465k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
465k
{                                                   \
710
465k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
465k
    nextOp ();                                      \
712
465k
}                                                   \
m3_compile.c:op_u64_Trunc_f32_r_r
Line
Count
Source
708
672k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
672k
{                                                   \
710
672k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
672k
    nextOp ();                                      \
712
672k
}                                                   \
m3_compile.c:op_i64_Trunc_f64_r_r
Line
Count
Source
708
602k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
602k
{                                                   \
710
602k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
602k
    nextOp ();                                      \
712
602k
}                                                   \
m3_compile.c:op_u64_Trunc_f64_r_r
Line
Count
Source
708
621k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
621k
{                                                   \
710
621k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
621k
    nextOp ();                                      \
712
621k
}                                                   \
m3_compile.c:op_i32_TruncSat_f32_r_r
Line
Count
Source
708
1.14M
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
1.14M
{                                                   \
710
1.14M
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
1.14M
    nextOp ();                                      \
712
1.14M
}                                                   \
m3_compile.c:op_u32_TruncSat_f32_r_r
Line
Count
Source
708
1.23M
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
1.23M
{                                                   \
710
1.23M
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
1.23M
    nextOp ();                                      \
712
1.23M
}                                                   \
m3_compile.c:op_i32_TruncSat_f64_r_r
Line
Count
Source
708
1.25M
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
1.25M
{                                                   \
710
1.25M
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
1.25M
    nextOp ();                                      \
712
1.25M
}                                                   \
m3_compile.c:op_u32_TruncSat_f64_r_r
Line
Count
Source
708
1.07M
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
1.07M
{                                                   \
710
1.07M
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
1.07M
    nextOp ();                                      \
712
1.07M
}                                                   \
m3_compile.c:op_i64_TruncSat_f32_r_r
Line
Count
Source
708
1.09M
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
1.09M
{                                                   \
710
1.09M
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
1.09M
    nextOp ();                                      \
712
1.09M
}                                                   \
m3_compile.c:op_u64_TruncSat_f32_r_r
Line
Count
Source
708
820k
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
820k
{                                                   \
710
820k
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
820k
    nextOp ();                                      \
712
820k
}                                                   \
m3_compile.c:op_i64_TruncSat_f64_r_r
Line
Count
Source
708
1.19M
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
1.19M
{                                                   \
710
1.19M
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
1.19M
    nextOp ();                                      \
712
1.19M
}                                                   \
m3_compile.c:op_u64_TruncSat_f64_r_r
Line
Count
Source
708
1.10M
d_m3Op(TYPE##_##NAME##_##FROM##_r_r)                \
709
1.10M
{                                                   \
710
1.10M
    OP((DEST), (FROM) SRC, ##__VA_ARGS__);          \
711
1.10M
    nextOp ();                                      \
712
1.10M
}                                                   \
713
18.7M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
18.7M
{                                                   \
715
18.7M
    FROM * stack = slot_ptr (FROM);                 \
716
18.7M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
18.7M
    nextOp ();                                      \
718
7.04M
}                                                   \
m3_compile.c:op_i32_Trunc_f32_r_s
Line
Count
Source
713
919k
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
919k
{                                                   \
715
919k
    FROM * stack = slot_ptr (FROM);                 \
716
919k
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
919k
    nextOp ();                                      \
718
919k
}                                                   \
m3_compile.c:op_u32_Trunc_f32_r_s
Line
Count
Source
713
1.12M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
1.12M
{                                                   \
715
1.12M
    FROM * stack = slot_ptr (FROM);                 \
716
1.12M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
1.12M
    nextOp ();                                      \
718
1.12M
}                                                   \
m3_compile.c:op_i32_Trunc_f64_r_s
Line
Count
Source
713
530k
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
530k
{                                                   \
715
530k
    FROM * stack = slot_ptr (FROM);                 \
716
530k
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
530k
    nextOp ();                                      \
718
530k
}                                                   \
m3_compile.c:op_u32_Trunc_f64_r_s
Line
Count
Source
713
689k
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
689k
{                                                   \
715
689k
    FROM * stack = slot_ptr (FROM);                 \
716
689k
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
689k
    nextOp ();                                      \
718
689k
}                                                   \
m3_compile.c:op_i64_Trunc_f32_r_s
Line
Count
Source
713
1.50M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
1.50M
{                                                   \
715
1.50M
    FROM * stack = slot_ptr (FROM);                 \
716
1.50M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
1.50M
    nextOp ();                                      \
718
1.50M
}                                                   \
m3_compile.c:op_u64_Trunc_f32_r_s
Line
Count
Source
713
880k
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
880k
{                                                   \
715
880k
    FROM * stack = slot_ptr (FROM);                 \
716
880k
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
880k
    nextOp ();                                      \
718
880k
}                                                   \
m3_compile.c:op_i64_Trunc_f64_r_s
Line
Count
Source
713
769k
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
769k
{                                                   \
715
769k
    FROM * stack = slot_ptr (FROM);                 \
716
769k
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
769k
    nextOp ();                                      \
718
769k
}                                                   \
m3_compile.c:op_u64_Trunc_f64_r_s
Line
Count
Source
713
627k
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
627k
{                                                   \
715
627k
    FROM * stack = slot_ptr (FROM);                 \
716
627k
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
627k
    nextOp ();                                      \
718
627k
}                                                   \
m3_compile.c:op_i32_TruncSat_f32_r_s
Line
Count
Source
713
2.03M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
2.03M
{                                                   \
715
2.03M
    FROM * stack = slot_ptr (FROM);                 \
716
2.03M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
2.03M
    nextOp ();                                      \
718
2.03M
}                                                   \
m3_compile.c:op_u32_TruncSat_f32_r_s
Line
Count
Source
713
1.94M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
1.94M
{                                                   \
715
1.94M
    FROM * stack = slot_ptr (FROM);                 \
716
1.94M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
1.94M
    nextOp ();                                      \
718
1.94M
}                                                   \
m3_compile.c:op_i32_TruncSat_f64_r_s
Line
Count
Source
713
1.15M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
1.15M
{                                                   \
715
1.15M
    FROM * stack = slot_ptr (FROM);                 \
716
1.15M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
1.15M
    nextOp ();                                      \
718
1.15M
}                                                   \
m3_compile.c:op_u32_TruncSat_f64_r_s
Line
Count
Source
713
1.46M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
1.46M
{                                                   \
715
1.46M
    FROM * stack = slot_ptr (FROM);                 \
716
1.46M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
1.46M
    nextOp ();                                      \
718
1.46M
}                                                   \
m3_compile.c:op_i64_TruncSat_f32_r_s
Line
Count
Source
713
1.53M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
1.53M
{                                                   \
715
1.53M
    FROM * stack = slot_ptr (FROM);                 \
716
1.53M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
1.53M
    nextOp ();                                      \
718
1.53M
}                                                   \
m3_compile.c:op_u64_TruncSat_f32_r_s
Line
Count
Source
713
1.64M
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
1.64M
{                                                   \
715
1.64M
    FROM * stack = slot_ptr (FROM);                 \
716
1.64M
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
1.64M
    nextOp ();                                      \
718
1.64M
}                                                   \
m3_compile.c:op_i64_TruncSat_f64_r_s
Line
Count
Source
713
962k
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
962k
{                                                   \
715
962k
    FROM * stack = slot_ptr (FROM);                 \
716
962k
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
962k
    nextOp ();                                      \
718
962k
}                                                   \
m3_compile.c:op_u64_TruncSat_f64_r_s
Line
Count
Source
713
925k
d_m3Op(TYPE##_##NAME##_##FROM##_r_s)                \
714
925k
{                                                   \
715
925k
    FROM * stack = slot_ptr (FROM);                 \
716
925k
    OP((DEST), (* stack), ##__VA_ARGS__);           \
717
925k
    nextOp ();                                      \
718
925k
}                                                   \
719
11.8M
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
11.8M
{                                                   \
721
11.8M
    TYPE * dest = slot_ptr (TYPE);                  \
722
11.8M
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
11.8M
    nextOp ();                                      \
724
3.00M
}                                                   \
m3_compile.c:op_i32_Trunc_f32_s_r
Line
Count
Source
719
484k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
484k
{                                                   \
721
484k
    TYPE * dest = slot_ptr (TYPE);                  \
722
484k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
484k
    nextOp ();                                      \
724
484k
}                                                   \
m3_compile.c:op_u32_Trunc_f32_s_r
Line
Count
Source
719
438k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
438k
{                                                   \
721
438k
    TYPE * dest = slot_ptr (TYPE);                  \
722
438k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
438k
    nextOp ();                                      \
724
438k
}                                                   \
m3_compile.c:op_i32_Trunc_f64_s_r
Line
Count
Source
719
355k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
355k
{                                                   \
721
355k
    TYPE * dest = slot_ptr (TYPE);                  \
722
355k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
355k
    nextOp ();                                      \
724
355k
}                                                   \
m3_compile.c:op_u32_Trunc_f64_s_r
Line
Count
Source
719
390k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
390k
{                                                   \
721
390k
    TYPE * dest = slot_ptr (TYPE);                  \
722
390k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
390k
    nextOp ();                                      \
724
390k
}                                                   \
m3_compile.c:op_i64_Trunc_f32_s_r
Line
Count
Source
719
432k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
432k
{                                                   \
721
432k
    TYPE * dest = slot_ptr (TYPE);                  \
722
432k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
432k
    nextOp ();                                      \
724
432k
}                                                   \
m3_compile.c:op_u64_Trunc_f32_s_r
Line
Count
Source
719
302k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
302k
{                                                   \
721
302k
    TYPE * dest = slot_ptr (TYPE);                  \
722
302k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
302k
    nextOp ();                                      \
724
302k
}                                                   \
m3_compile.c:op_i64_Trunc_f64_s_r
Line
Count
Source
719
316k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
316k
{                                                   \
721
316k
    TYPE * dest = slot_ptr (TYPE);                  \
722
316k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
316k
    nextOp ();                                      \
724
316k
}                                                   \
m3_compile.c:op_u64_Trunc_f64_s_r
Line
Count
Source
719
282k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
282k
{                                                   \
721
282k
    TYPE * dest = slot_ptr (TYPE);                  \
722
282k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
282k
    nextOp ();                                      \
724
282k
}                                                   \
m3_compile.c:op_i32_TruncSat_f32_s_r
Line
Count
Source
719
910k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
910k
{                                                   \
721
910k
    TYPE * dest = slot_ptr (TYPE);                  \
722
910k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
910k
    nextOp ();                                      \
724
910k
}                                                   \
m3_compile.c:op_u32_TruncSat_f32_s_r
Line
Count
Source
719
1.26M
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
1.26M
{                                                   \
721
1.26M
    TYPE * dest = slot_ptr (TYPE);                  \
722
1.26M
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
1.26M
    nextOp ();                                      \
724
1.26M
}                                                   \
m3_compile.c:op_i32_TruncSat_f64_s_r
Line
Count
Source
719
1.28M
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
1.28M
{                                                   \
721
1.28M
    TYPE * dest = slot_ptr (TYPE);                  \
722
1.28M
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
1.28M
    nextOp ();                                      \
724
1.28M
}                                                   \
m3_compile.c:op_u32_TruncSat_f64_s_r
Line
Count
Source
719
888k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
888k
{                                                   \
721
888k
    TYPE * dest = slot_ptr (TYPE);                  \
722
888k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
888k
    nextOp ();                                      \
724
888k
}                                                   \
m3_compile.c:op_i64_TruncSat_f32_s_r
Line
Count
Source
719
1.03M
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
1.03M
{                                                   \
721
1.03M
    TYPE * dest = slot_ptr (TYPE);                  \
722
1.03M
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
1.03M
    nextOp ();                                      \
724
1.03M
}                                                   \
m3_compile.c:op_u64_TruncSat_f32_s_r
Line
Count
Source
719
1.28M
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
1.28M
{                                                   \
721
1.28M
    TYPE * dest = slot_ptr (TYPE);                  \
722
1.28M
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
1.28M
    nextOp ();                                      \
724
1.28M
}                                                   \
m3_compile.c:op_i64_TruncSat_f64_s_r
Line
Count
Source
719
1.37M
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
1.37M
{                                                   \
721
1.37M
    TYPE * dest = slot_ptr (TYPE);                  \
722
1.37M
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
1.37M
    nextOp ();                                      \
724
1.37M
}                                                   \
m3_compile.c:op_u64_TruncSat_f64_s_r
Line
Count
Source
719
847k
d_m3Op(TYPE##_##NAME##_##FROM##_s_r)                \
720
847k
{                                                   \
721
847k
    TYPE * dest = slot_ptr (TYPE);                  \
722
847k
    OP((* dest), (FROM) SRC, ##__VA_ARGS__);        \
723
847k
    nextOp ();                                      \
724
847k
}                                                   \
725
21.3M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
21.3M
{                                                   \
727
21.3M
    FROM * stack = slot_ptr (FROM);                 \
728
21.3M
    TYPE * dest = slot_ptr (TYPE);                  \
729
21.3M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
21.3M
    nextOp ();                                      \
731
5.49M
}
m3_compile.c:op_i32_Trunc_f32_s_s
Line
Count
Source
725
972k
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
972k
{                                                   \
727
972k
    FROM * stack = slot_ptr (FROM);                 \
728
972k
    TYPE * dest = slot_ptr (TYPE);                  \
729
972k
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
972k
    nextOp ();                                      \
731
972k
}
m3_compile.c:op_u32_Trunc_f32_s_s
Line
Count
Source
725
824k
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
824k
{                                                   \
727
824k
    FROM * stack = slot_ptr (FROM);                 \
728
824k
    TYPE * dest = slot_ptr (TYPE);                  \
729
824k
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
824k
    nextOp ();                                      \
731
824k
}
m3_compile.c:op_i32_Trunc_f64_s_s
Line
Count
Source
725
520k
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
520k
{                                                   \
727
520k
    FROM * stack = slot_ptr (FROM);                 \
728
520k
    TYPE * dest = slot_ptr (TYPE);                  \
729
520k
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
520k
    nextOp ();                                      \
731
520k
}
m3_compile.c:op_u32_Trunc_f64_s_s
Line
Count
Source
725
449k
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
449k
{                                                   \
727
449k
    FROM * stack = slot_ptr (FROM);                 \
728
449k
    TYPE * dest = slot_ptr (TYPE);                  \
729
449k
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
449k
    nextOp ();                                      \
731
449k
}
m3_compile.c:op_i64_Trunc_f32_s_s
Line
Count
Source
725
1.21M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
1.21M
{                                                   \
727
1.21M
    FROM * stack = slot_ptr (FROM);                 \
728
1.21M
    TYPE * dest = slot_ptr (TYPE);                  \
729
1.21M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
1.21M
    nextOp ();                                      \
731
1.21M
}
m3_compile.c:op_u64_Trunc_f32_s_s
Line
Count
Source
725
812k
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
812k
{                                                   \
727
812k
    FROM * stack = slot_ptr (FROM);                 \
728
812k
    TYPE * dest = slot_ptr (TYPE);                  \
729
812k
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
812k
    nextOp ();                                      \
731
812k
}
m3_compile.c:op_i64_Trunc_f64_s_s
Line
Count
Source
725
231k
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
231k
{                                                   \
727
231k
    FROM * stack = slot_ptr (FROM);                 \
728
231k
    TYPE * dest = slot_ptr (TYPE);                  \
729
231k
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
231k
    nextOp ();                                      \
731
231k
}
m3_compile.c:op_u64_Trunc_f64_s_s
Line
Count
Source
725
477k
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
477k
{                                                   \
727
477k
    FROM * stack = slot_ptr (FROM);                 \
728
477k
    TYPE * dest = slot_ptr (TYPE);                  \
729
477k
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
477k
    nextOp ();                                      \
731
477k
}
m3_compile.c:op_i32_TruncSat_f32_s_s
Line
Count
Source
725
2.84M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
2.84M
{                                                   \
727
2.84M
    FROM * stack = slot_ptr (FROM);                 \
728
2.84M
    TYPE * dest = slot_ptr (TYPE);                  \
729
2.84M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
2.84M
    nextOp ();                                      \
731
2.84M
}
m3_compile.c:op_u32_TruncSat_f32_s_s
Line
Count
Source
725
2.77M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
2.77M
{                                                   \
727
2.77M
    FROM * stack = slot_ptr (FROM);                 \
728
2.77M
    TYPE * dest = slot_ptr (TYPE);                  \
729
2.77M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
2.77M
    nextOp ();                                      \
731
2.77M
}
m3_compile.c:op_i32_TruncSat_f64_s_s
Line
Count
Source
725
793k
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
793k
{                                                   \
727
793k
    FROM * stack = slot_ptr (FROM);                 \
728
793k
    TYPE * dest = slot_ptr (TYPE);                  \
729
793k
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
793k
    nextOp ();                                      \
731
793k
}
m3_compile.c:op_u32_TruncSat_f64_s_s
Line
Count
Source
725
1.13M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
1.13M
{                                                   \
727
1.13M
    FROM * stack = slot_ptr (FROM);                 \
728
1.13M
    TYPE * dest = slot_ptr (TYPE);                  \
729
1.13M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
1.13M
    nextOp ();                                      \
731
1.13M
}
m3_compile.c:op_i64_TruncSat_f32_s_s
Line
Count
Source
725
2.98M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
2.98M
{                                                   \
727
2.98M
    FROM * stack = slot_ptr (FROM);                 \
728
2.98M
    TYPE * dest = slot_ptr (TYPE);                  \
729
2.98M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
2.98M
    nextOp ();                                      \
731
2.98M
}
m3_compile.c:op_u64_TruncSat_f32_s_s
Line
Count
Source
725
2.76M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
2.76M
{                                                   \
727
2.76M
    FROM * stack = slot_ptr (FROM);                 \
728
2.76M
    TYPE * dest = slot_ptr (TYPE);                  \
729
2.76M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
2.76M
    nextOp ();                                      \
731
2.76M
}
m3_compile.c:op_i64_TruncSat_f64_s_s
Line
Count
Source
725
1.04M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
1.04M
{                                                   \
727
1.04M
    FROM * stack = slot_ptr (FROM);                 \
728
1.04M
    TYPE * dest = slot_ptr (TYPE);                  \
729
1.04M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
1.04M
    nextOp ();                                      \
731
1.04M
}
m3_compile.c:op_u64_TruncSat_f64_s_s
Line
Count
Source
725
1.53M
d_m3Op(TYPE##_##NAME##_##FROM##_s_s)                \
726
1.53M
{                                                   \
727
1.53M
    FROM * stack = slot_ptr (FROM);                 \
728
1.53M
    TYPE * dest = slot_ptr (TYPE);                  \
729
1.53M
    OP((* dest), (* stack), ##__VA_ARGS__);         \
730
1.53M
    nextOp ();                                      \
731
1.53M
}
732
733
#if d_m3HasFloat
734
3.01M
d_m3TruncMacro(_r0, _fp0, i32, Trunc, f32, OP_I32_TRUNC_F32)
735
3.19M
d_m3TruncMacro(_r0, _fp0, u32, Trunc, f32, OP_U32_TRUNC_F32)
736
2.11M
d_m3TruncMacro(_r0, _fp0, i32, Trunc, f64, OP_I32_TRUNC_F64)
737
2.40M
d_m3TruncMacro(_r0, _fp0, u32, Trunc, f64, OP_U32_TRUNC_F64)
738
739
3.61M
d_m3TruncMacro(_r0, _fp0, i64, Trunc, f32, OP_I64_TRUNC_F32)
740
2.66M
d_m3TruncMacro(_r0, _fp0, u64, Trunc, f32, OP_U64_TRUNC_F32)
741
1.92M
d_m3TruncMacro(_r0, _fp0, i64, Trunc, f64, OP_I64_TRUNC_F64)
742
2.00M
d_m3TruncMacro(_r0, _fp0, u64, Trunc, f64, OP_U64_TRUNC_F64)
743
744
6.93M
d_m3TruncMacro(_r0, _fp0, i32, TruncSat, f32, OP_I32_TRUNC_SAT_F32)
745
7.22M
d_m3TruncMacro(_r0, _fp0, u32, TruncSat, f32, OP_U32_TRUNC_SAT_F32)
746
4.49M
d_m3TruncMacro(_r0, _fp0, i32, TruncSat, f64, OP_I32_TRUNC_SAT_F64)
747
4.55M
d_m3TruncMacro(_r0, _fp0, u32, TruncSat, f64, OP_U32_TRUNC_SAT_F64)
748
749
6.65M
d_m3TruncMacro(_r0, _fp0, i64, TruncSat, f32, OP_I64_TRUNC_SAT_F32)
750
6.51M
d_m3TruncMacro(_r0, _fp0, u64, TruncSat, f32, OP_U64_TRUNC_SAT_F32)
751
4.57M
d_m3TruncMacro(_r0, _fp0, i64, TruncSat, f64, OP_I64_TRUNC_SAT_F64)
752
4.41M
d_m3TruncMacro(_r0, _fp0, u64, TruncSat, f64, OP_U64_TRUNC_SAT_F64)
753
#endif
754
755
#define d_m3TypeModifyOp(REG_TO, REG_FROM, TO, NAME, FROM)  \
756
3.45M
d_m3Op(TO##_##NAME##_##FROM##_r)                            \
757
3.45M
{                                                           \
758
3.45M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
759
3.45M
    nextOp ();                                              \
760
3.45M
}                                                           \
m3_compile.c:op_i64_Extend_i32_r
Line
Count
Source
756
1.84M
d_m3Op(TO##_##NAME##_##FROM##_r)                            \
757
1.84M
{                                                           \
758
1.84M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
759
1.84M
    nextOp ();                                              \
760
1.84M
}                                                           \
m3_compile.c:op_i64_Extend_u32_r
Line
Count
Source
756
1.60M
d_m3Op(TO##_##NAME##_##FROM##_r)                            \
757
1.60M
{                                                           \
758
1.60M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
759
1.60M
    nextOp ();                                              \
760
1.60M
}                                                           \
761
                                                            \
762
2.54M
d_m3Op(TO##_##NAME##_##FROM##_s)                            \
763
2.54M
{                                                           \
764
2.54M
    FROM from = slot (FROM);                                \
765
2.54M
    REG_TO = (TO) (from);                                   \
766
2.54M
    nextOp ();                                              \
767
2.54M
}
m3_compile.c:op_i64_Extend_i32_s
Line
Count
Source
762
1.40M
d_m3Op(TO##_##NAME##_##FROM##_s)                            \
763
1.40M
{                                                           \
764
1.40M
    FROM from = slot (FROM);                                \
765
1.40M
    REG_TO = (TO) (from);                                   \
766
1.40M
    nextOp ();                                              \
767
1.40M
}
m3_compile.c:op_i64_Extend_u32_s
Line
Count
Source
762
1.14M
d_m3Op(TO##_##NAME##_##FROM##_s)                            \
763
1.14M
{                                                           \
764
1.14M
    FROM from = slot (FROM);                                \
765
1.14M
    REG_TO = (TO) (from);                                   \
766
1.14M
    nextOp ();                                              \
767
1.14M
}
768
769
// Int to int
770
d_m3TypeModifyOp(_r0, _r0, i64, Extend, i32);
771
d_m3TypeModifyOp(_r0, _r0, i64, Extend, u32);
772
773
// Float to float. Narrowing or widening a NaN produces an arithmetic one, so these
774
// two go through the canonicalizer where the int conversions have nothing to do.
775
#define d_m3FloatModifyOp(TO, NAME, FROM)                   \
776
1.48M
d_m3Op(TO##_##NAME##_##FROM##_r)                            \
777
1.48M
{                                                           \
778
1.48M
    _fp0 = canon_nan_##TO ((TO) ((FROM) _fp0));             \
779
1.48M
    nextOp ();                                              \
780
1.48M
}                                                           \
m3_compile.c:op_f32_Demote_f64_r
Line
Count
Source
776
694k
d_m3Op(TO##_##NAME##_##FROM##_r)                            \
777
694k
{                                                           \
778
694k
    _fp0 = canon_nan_##TO ((TO) ((FROM) _fp0));             \
779
694k
    nextOp ();                                              \
780
694k
}                                                           \
m3_compile.c:op_f64_Promote_f32_r
Line
Count
Source
776
787k
d_m3Op(TO##_##NAME##_##FROM##_r)                            \
777
787k
{                                                           \
778
787k
    _fp0 = canon_nan_##TO ((TO) ((FROM) _fp0));             \
779
787k
    nextOp ();                                              \
780
787k
}                                                           \
781
                                                            \
782
3.08M
d_m3Op(TO##_##NAME##_##FROM##_s)                            \
783
3.08M
{                                                           \
784
3.08M
    FROM from = slot (FROM);                                \
785
3.08M
    _fp0 = canon_nan_##TO ((TO) (from));                    \
786
3.08M
    nextOp ();                                              \
787
3.08M
}
m3_compile.c:op_f32_Demote_f64_s
Line
Count
Source
782
383k
d_m3Op(TO##_##NAME##_##FROM##_s)                            \
783
383k
{                                                           \
784
383k
    FROM from = slot (FROM);                                \
785
383k
    _fp0 = canon_nan_##TO ((TO) (from));                    \
786
383k
    nextOp ();                                              \
787
383k
}
m3_compile.c:op_f64_Promote_f32_s
Line
Count
Source
782
2.69M
d_m3Op(TO##_##NAME##_##FROM##_s)                            \
783
2.69M
{                                                           \
784
2.69M
    FROM from = slot (FROM);                                \
785
2.69M
    _fp0 = canon_nan_##TO ((TO) (from));                    \
786
2.69M
    nextOp ();                                              \
787
2.69M
}
788
789
#if d_m3HasFloat
790
d_m3FloatModifyOp(f32, Demote, f64);
791
d_m3FloatModifyOp(f64, Promote, f32);
792
#endif
793
794
#define d_m3TypeConvertOp(REG_TO, REG_FROM, TO, NAME, FROM) \
795
14.4M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
14.4M
{                                                           \
797
14.4M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
14.4M
    nextOp ();                                              \
799
14.4M
}                                                           \
m3_compile.c:op_f32_Convert_i32_r_r
Line
Count
Source
795
2.29M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
2.29M
{                                                           \
797
2.29M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
2.29M
    nextOp ();                                              \
799
2.29M
}                                                           \
m3_compile.c:op_f32_Convert_u32_r_r
Line
Count
Source
795
1.80M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
1.80M
{                                                           \
797
1.80M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
1.80M
    nextOp ();                                              \
799
1.80M
}                                                           \
m3_compile.c:op_f32_Convert_i64_r_r
Line
Count
Source
795
1.60M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
1.60M
{                                                           \
797
1.60M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
1.60M
    nextOp ();                                              \
799
1.60M
}                                                           \
m3_compile.c:op_f32_Convert_u64_r_r
Line
Count
Source
795
1.17M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
1.17M
{                                                           \
797
1.17M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
1.17M
    nextOp ();                                              \
799
1.17M
}                                                           \
m3_compile.c:op_f64_Convert_i32_r_r
Line
Count
Source
795
2.83M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
2.83M
{                                                           \
797
2.83M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
2.83M
    nextOp ();                                              \
799
2.83M
}                                                           \
m3_compile.c:op_f64_Convert_u32_r_r
Line
Count
Source
795
1.63M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
1.63M
{                                                           \
797
1.63M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
1.63M
    nextOp ();                                              \
799
1.63M
}                                                           \
m3_compile.c:op_f64_Convert_i64_r_r
Line
Count
Source
795
1.09M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
1.09M
{                                                           \
797
1.09M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
1.09M
    nextOp ();                                              \
799
1.09M
}                                                           \
m3_compile.c:op_f64_Convert_u64_r_r
Line
Count
Source
795
2.00M
d_m3Op(TO##_##NAME##_##FROM##_r_r)                          \
796
2.00M
{                                                           \
797
2.00M
    REG_TO = (TO) ((FROM) REG_FROM);                        \
798
2.00M
    nextOp ();                                              \
799
2.00M
}                                                           \
800
                                                            \
801
5.52M
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
5.52M
{                                                           \
803
5.52M
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
5.52M
    nextOp ();                                              \
805
5.52M
}                                                           \
m3_compile.c:op_f32_Convert_i32_s_r
Line
Count
Source
801
823k
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
823k
{                                                           \
803
823k
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
823k
    nextOp ();                                              \
805
823k
}                                                           \
m3_compile.c:op_f32_Convert_u32_s_r
Line
Count
Source
801
1.03M
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
1.03M
{                                                           \
803
1.03M
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
1.03M
    nextOp ();                                              \
805
1.03M
}                                                           \
m3_compile.c:op_f32_Convert_i64_s_r
Line
Count
Source
801
477k
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
477k
{                                                           \
803
477k
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
477k
    nextOp ();                                              \
805
477k
}                                                           \
m3_compile.c:op_f32_Convert_u64_s_r
Line
Count
Source
801
361k
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
361k
{                                                           \
803
361k
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
361k
    nextOp ();                                              \
805
361k
}                                                           \
m3_compile.c:op_f64_Convert_i32_s_r
Line
Count
Source
801
1.08M
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
1.08M
{                                                           \
803
1.08M
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
1.08M
    nextOp ();                                              \
805
1.08M
}                                                           \
m3_compile.c:op_f64_Convert_u32_s_r
Line
Count
Source
801
759k
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
759k
{                                                           \
803
759k
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
759k
    nextOp ();                                              \
805
759k
}                                                           \
m3_compile.c:op_f64_Convert_i64_s_r
Line
Count
Source
801
405k
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
405k
{                                                           \
803
405k
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
405k
    nextOp ();                                              \
805
405k
}                                                           \
m3_compile.c:op_f64_Convert_u64_s_r
Line
Count
Source
801
588k
d_m3Op(TO##_##NAME##_##FROM##_s_r)                          \
802
588k
{                                                           \
803
588k
    slot (TO) = (TO) ((FROM) REG_FROM);                     \
804
588k
    nextOp ();                                              \
805
588k
}                                                           \
806
                                                            \
807
25.0M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
25.0M
{                                                           \
809
25.0M
    FROM from = slot (FROM);                                \
810
25.0M
    REG_TO = (TO) (from);                                   \
811
25.0M
    nextOp ();                                              \
812
25.0M
}                                                           \
m3_compile.c:op_f32_Convert_i32_r_s
Line
Count
Source
807
2.54M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
2.54M
{                                                           \
809
2.54M
    FROM from = slot (FROM);                                \
810
2.54M
    REG_TO = (TO) (from);                                   \
811
2.54M
    nextOp ();                                              \
812
2.54M
}                                                           \
m3_compile.c:op_f32_Convert_u32_r_s
Line
Count
Source
807
2.33M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
2.33M
{                                                           \
809
2.33M
    FROM from = slot (FROM);                                \
810
2.33M
    REG_TO = (TO) (from);                                   \
811
2.33M
    nextOp ();                                              \
812
2.33M
}                                                           \
m3_compile.c:op_f32_Convert_i64_r_s
Line
Count
Source
807
3.23M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
3.23M
{                                                           \
809
3.23M
    FROM from = slot (FROM);                                \
810
3.23M
    REG_TO = (TO) (from);                                   \
811
3.23M
    nextOp ();                                              \
812
3.23M
}                                                           \
m3_compile.c:op_f32_Convert_u64_r_s
Line
Count
Source
807
3.37M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
3.37M
{                                                           \
809
3.37M
    FROM from = slot (FROM);                                \
810
3.37M
    REG_TO = (TO) (from);                                   \
811
3.37M
    nextOp ();                                              \
812
3.37M
}                                                           \
m3_compile.c:op_f64_Convert_i32_r_s
Line
Count
Source
807
3.08M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
3.08M
{                                                           \
809
3.08M
    FROM from = slot (FROM);                                \
810
3.08M
    REG_TO = (TO) (from);                                   \
811
3.08M
    nextOp ();                                              \
812
3.08M
}                                                           \
m3_compile.c:op_f64_Convert_u32_r_s
Line
Count
Source
807
2.98M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
2.98M
{                                                           \
809
2.98M
    FROM from = slot (FROM);                                \
810
2.98M
    REG_TO = (TO) (from);                                   \
811
2.98M
    nextOp ();                                              \
812
2.98M
}                                                           \
m3_compile.c:op_f64_Convert_i64_r_s
Line
Count
Source
807
3.66M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
3.66M
{                                                           \
809
3.66M
    FROM from = slot (FROM);                                \
810
3.66M
    REG_TO = (TO) (from);                                   \
811
3.66M
    nextOp ();                                              \
812
3.66M
}                                                           \
m3_compile.c:op_f64_Convert_u64_r_s
Line
Count
Source
807
3.84M
d_m3Op(TO##_##NAME##_##FROM##_r_s)                          \
808
3.84M
{                                                           \
809
3.84M
    FROM from = slot (FROM);                                \
810
3.84M
    REG_TO = (TO) (from);                                   \
811
3.84M
    nextOp ();                                              \
812
3.84M
}                                                           \
813
                                                            \
814
9.27M
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
9.27M
{                                                           \
816
9.27M
    FROM from = slot (FROM);                                \
817
9.27M
    slot (TO) = (TO) (from);                                \
818
9.27M
    nextOp ();                                              \
819
9.27M
}
m3_compile.c:op_f32_Convert_i32_s_s
Line
Count
Source
814
1.04M
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
1.04M
{                                                           \
816
1.04M
    FROM from = slot (FROM);                                \
817
1.04M
    slot (TO) = (TO) (from);                                \
818
1.04M
    nextOp ();                                              \
819
1.04M
}
m3_compile.c:op_f32_Convert_u32_s_s
Line
Count
Source
814
865k
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
865k
{                                                           \
816
865k
    FROM from = slot (FROM);                                \
817
865k
    slot (TO) = (TO) (from);                                \
818
865k
    nextOp ();                                              \
819
865k
}
m3_compile.c:op_f32_Convert_i64_s_s
Line
Count
Source
814
624k
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
624k
{                                                           \
816
624k
    FROM from = slot (FROM);                                \
817
624k
    slot (TO) = (TO) (from);                                \
818
624k
    nextOp ();                                              \
819
624k
}
m3_compile.c:op_f32_Convert_u64_s_s
Line
Count
Source
814
912k
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
912k
{                                                           \
816
912k
    FROM from = slot (FROM);                                \
817
912k
    slot (TO) = (TO) (from);                                \
818
912k
    nextOp ();                                              \
819
912k
}
m3_compile.c:op_f64_Convert_i32_s_s
Line
Count
Source
814
1.67M
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
1.67M
{                                                           \
816
1.67M
    FROM from = slot (FROM);                                \
817
1.67M
    slot (TO) = (TO) (from);                                \
818
1.67M
    nextOp ();                                              \
819
1.67M
}
m3_compile.c:op_f64_Convert_u32_s_s
Line
Count
Source
814
1.04M
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
1.04M
{                                                           \
816
1.04M
    FROM from = slot (FROM);                                \
817
1.04M
    slot (TO) = (TO) (from);                                \
818
1.04M
    nextOp ();                                              \
819
1.04M
}
m3_compile.c:op_f64_Convert_i64_s_s
Line
Count
Source
814
1.64M
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
1.64M
{                                                           \
816
1.64M
    FROM from = slot (FROM);                                \
817
1.64M
    slot (TO) = (TO) (from);                                \
818
1.64M
    nextOp ();                                              \
819
1.64M
}
m3_compile.c:op_f64_Convert_u64_s_s
Line
Count
Source
814
1.45M
d_m3Op(TO##_##NAME##_##FROM##_s_s)                          \
815
1.45M
{                                                           \
816
1.45M
    FROM from = slot (FROM);                                \
817
1.45M
    slot (TO) = (TO) (from);                                \
818
1.45M
    nextOp ();                                              \
819
1.45M
}
820
821
// Int to float
822
#if d_m3HasFloat
823
d_m3TypeConvertOp(_fp0, _r0, f64, Convert, i32);
824
d_m3TypeConvertOp(_fp0, _r0, f64, Convert, u32);
825
d_m3TypeConvertOp(_fp0, _r0, f64, Convert, i64);
826
d_m3TypeConvertOp(_fp0, _r0, f64, Convert, u64);
827
828
d_m3TypeConvertOp(_fp0, _r0, f32, Convert, i32);
829
d_m3TypeConvertOp(_fp0, _r0, f32, Convert, u32);
830
d_m3TypeConvertOp(_fp0, _r0, f32, Convert, i64);
831
d_m3TypeConvertOp(_fp0, _r0, f32, Convert, u64);
832
#endif
833
834
#define d_m3ReinterpretOp(REG, TO, SRC, FROM)               \
835
5.16M
d_m3Op(TO##_Reinterpret_##FROM##_r_r)                       \
836
5.16M
{                                                           \
837
5.16M
    union { FROM c; TO t; } u;                              \
838
5.16M
    u.c = (FROM) SRC;                                       \
839
5.16M
    REG = u.t;                                              \
840
5.16M
    nextOp ();                                              \
841
5.16M
}                                                           \
m3_compile.c:op_i32_Reinterpret_f32_r_r
Line
Count
Source
835
733k
d_m3Op(TO##_Reinterpret_##FROM##_r_r)                       \
836
733k
{                                                           \
837
733k
    union { FROM c; TO t; } u;                              \
838
733k
    u.c = (FROM) SRC;                                       \
839
733k
    REG = u.t;                                              \
840
733k
    nextOp ();                                              \
841
733k
}                                                           \
m3_compile.c:op_i64_Reinterpret_f64_r_r
Line
Count
Source
835
608k
d_m3Op(TO##_Reinterpret_##FROM##_r_r)                       \
836
608k
{                                                           \
837
608k
    union { FROM c; TO t; } u;                              \
838
608k
    u.c = (FROM) SRC;                                       \
839
608k
    REG = u.t;                                              \
840
608k
    nextOp ();                                              \
841
608k
}                                                           \
m3_compile.c:op_f32_Reinterpret_i32_r_r
Line
Count
Source
835
1.80M
d_m3Op(TO##_Reinterpret_##FROM##_r_r)                       \
836
1.80M
{                                                           \
837
1.80M
    union { FROM c; TO t; } u;                              \
838
1.80M
    u.c = (FROM) SRC;                                       \
839
1.80M
    REG = u.t;                                              \
840
1.80M
    nextOp ();                                              \
841
1.80M
}                                                           \
m3_compile.c:op_f64_Reinterpret_i64_r_r
Line
Count
Source
835
2.00M
d_m3Op(TO##_Reinterpret_##FROM##_r_r)                       \
836
2.00M
{                                                           \
837
2.00M
    union { FROM c; TO t; } u;                              \
838
2.00M
    u.c = (FROM) SRC;                                       \
839
2.00M
    REG = u.t;                                              \
840
2.00M
    nextOp ();                                              \
841
2.00M
}                                                           \
842
                                                            \
843
9.46M
d_m3Op(TO##_Reinterpret_##FROM##_r_s)                       \
844
9.46M
{                                                           \
845
9.46M
    union { FROM c; TO t; } u;                              \
846
9.46M
    u.c = slot (FROM);                                      \
847
9.46M
    REG = u.t;                                              \
848
9.46M
    nextOp ();                                              \
849
9.46M
}                                                           \
m3_compile.c:op_i32_Reinterpret_f32_r_s
Line
Count
Source
843
1.17M
d_m3Op(TO##_Reinterpret_##FROM##_r_s)                       \
844
1.17M
{                                                           \
845
1.17M
    union { FROM c; TO t; } u;                              \
846
1.17M
    u.c = slot (FROM);                                      \
847
1.17M
    REG = u.t;                                              \
848
1.17M
    nextOp ();                                              \
849
1.17M
}                                                           \
m3_compile.c:op_i64_Reinterpret_f64_r_s
Line
Count
Source
843
436k
d_m3Op(TO##_Reinterpret_##FROM##_r_s)                       \
844
436k
{                                                           \
845
436k
    union { FROM c; TO t; } u;                              \
846
436k
    u.c = slot (FROM);                                      \
847
436k
    REG = u.t;                                              \
848
436k
    nextOp ();                                              \
849
436k
}                                                           \
m3_compile.c:op_f32_Reinterpret_i32_r_s
Line
Count
Source
843
2.86M
d_m3Op(TO##_Reinterpret_##FROM##_r_s)                       \
844
2.86M
{                                                           \
845
2.86M
    union { FROM c; TO t; } u;                              \
846
2.86M
    u.c = slot (FROM);                                      \
847
2.86M
    REG = u.t;                                              \
848
2.86M
    nextOp ();                                              \
849
2.86M
}                                                           \
m3_compile.c:op_f64_Reinterpret_i64_r_s
Line
Count
Source
843
4.99M
d_m3Op(TO##_Reinterpret_##FROM##_r_s)                       \
844
4.99M
{                                                           \
845
4.99M
    union { FROM c; TO t; } u;                              \
846
4.99M
    u.c = slot (FROM);                                      \
847
4.99M
    REG = u.t;                                              \
848
4.99M
    nextOp ();                                              \
849
4.99M
}                                                           \
850
                                                            \
851
2.48M
d_m3Op(TO##_Reinterpret_##FROM##_s_r)                       \
852
2.48M
{                                                           \
853
2.48M
    union { FROM c; TO t; } u;                              \
854
2.48M
    u.c = (FROM) SRC;                                       \
855
2.48M
    slot (TO) = u.t;                                        \
856
2.48M
    nextOp ();                                              \
857
2.48M
}                                                           \
m3_compile.c:op_i32_Reinterpret_f32_s_r
Line
Count
Source
851
617k
d_m3Op(TO##_Reinterpret_##FROM##_s_r)                       \
852
617k
{                                                           \
853
617k
    union { FROM c; TO t; } u;                              \
854
617k
    u.c = (FROM) SRC;                                       \
855
617k
    slot (TO) = u.t;                                        \
856
617k
    nextOp ();                                              \
857
617k
}                                                           \
m3_compile.c:op_i64_Reinterpret_f64_s_r
Line
Count
Source
851
350k
d_m3Op(TO##_Reinterpret_##FROM##_s_r)                       \
852
350k
{                                                           \
853
350k
    union { FROM c; TO t; } u;                              \
854
350k
    u.c = (FROM) SRC;                                       \
855
350k
    slot (TO) = u.t;                                        \
856
350k
    nextOp ();                                              \
857
350k
}                                                           \
m3_compile.c:op_f32_Reinterpret_i32_s_r
Line
Count
Source
851
908k
d_m3Op(TO##_Reinterpret_##FROM##_s_r)                       \
852
908k
{                                                           \
853
908k
    union { FROM c; TO t; } u;                              \
854
908k
    u.c = (FROM) SRC;                                       \
855
908k
    slot (TO) = u.t;                                        \
856
908k
    nextOp ();                                              \
857
908k
}                                                           \
m3_compile.c:op_f64_Reinterpret_i64_s_r
Line
Count
Source
851
607k
d_m3Op(TO##_Reinterpret_##FROM##_s_r)                       \
852
607k
{                                                           \
853
607k
    union { FROM c; TO t; } u;                              \
854
607k
    u.c = (FROM) SRC;                                       \
855
607k
    slot (TO) = u.t;                                        \
856
607k
    nextOp ();                                              \
857
607k
}                                                           \
858
                                                            \
859
4.78M
d_m3Op(TO##_Reinterpret_##FROM##_s_s)                       \
860
4.78M
{                                                           \
861
4.78M
    union { FROM c; TO t; } u;                              \
862
4.78M
    u.c = slot (FROM);                                      \
863
4.78M
    slot (TO) = u.t;                                        \
864
4.78M
    nextOp ();                                              \
865
4.78M
}
m3_compile.c:op_i32_Reinterpret_f32_s_s
Line
Count
Source
859
1.43M
d_m3Op(TO##_Reinterpret_##FROM##_s_s)                       \
860
1.43M
{                                                           \
861
1.43M
    union { FROM c; TO t; } u;                              \
862
1.43M
    u.c = slot (FROM);                                      \
863
1.43M
    slot (TO) = u.t;                                        \
864
1.43M
    nextOp ();                                              \
865
1.43M
}
m3_compile.c:op_i64_Reinterpret_f64_s_s
Line
Count
Source
859
316k
d_m3Op(TO##_Reinterpret_##FROM##_s_s)                       \
860
316k
{                                                           \
861
316k
    union { FROM c; TO t; } u;                              \
862
316k
    u.c = slot (FROM);                                      \
863
316k
    slot (TO) = u.t;                                        \
864
316k
    nextOp ();                                              \
865
316k
}
m3_compile.c:op_f32_Reinterpret_i32_s_s
Line
Count
Source
859
840k
d_m3Op(TO##_Reinterpret_##FROM##_s_s)                       \
860
840k
{                                                           \
861
840k
    union { FROM c; TO t; } u;                              \
862
840k
    u.c = slot (FROM);                                      \
863
840k
    slot (TO) = u.t;                                        \
864
840k
    nextOp ();                                              \
865
840k
}
m3_compile.c:op_f64_Reinterpret_i64_s_s
Line
Count
Source
859
2.19M
d_m3Op(TO##_Reinterpret_##FROM##_s_s)                       \
860
2.19M
{                                                           \
861
2.19M
    union { FROM c; TO t; } u;                              \
862
2.19M
    u.c = slot (FROM);                                      \
863
2.19M
    slot (TO) = u.t;                                        \
864
2.19M
    nextOp ();                                              \
865
2.19M
}
866
867
#if d_m3HasFloat
868
d_m3ReinterpretOp(_r0, i32, _fp0, f32)
869
d_m3ReinterpretOp(_r0, i64, _fp0, f64)
870
d_m3ReinterpretOp(_fp0, f32, _r0, i32)
871
d_m3ReinterpretOp(_fp0, f64, _r0, i64)
872
#endif
873
874
// clang-format on
875
876
d_m3Op(GetGlobal_s32)
877
200k
{
878
200k
    u32* global = immediate(u32*);
879
200k
    slot(u32) = *global;                        //  printf ("get global: %p %" PRIi64 "\n", global, *global);
880
881
200k
    nextOp();
882
200k
}
883
884
885
d_m3Op(GetGlobal_s64)
886
41.6k
{
887
41.6k
    u64* global = immediate(u64*);
888
41.6k
    slot(u64) = *global;                        // printf ("get global: %p %" PRIi64 "\n", global, *global);
889
890
41.6k
    nextOp();
891
41.6k
}
892
893
894
d_m3Op(SetGlobal_i32)
895
90.6k
{
896
90.6k
    u32* global = immediate(u32*);
897
90.6k
    *global = (u32)_r0;                         //  printf ("set global: %p %" PRIi64 "\n", global, _r0);
898
899
90.6k
    nextOp();
900
90.6k
}
901
902
903
d_m3Op(SetGlobal_i64)
904
88.1k
{
905
88.1k
    u64* global = immediate(u64*);
906
88.1k
    *global = (u64)_r0;                         //  printf ("set global: %p %" PRIi64 "\n", global, _r0);
907
908
88.1k
    nextOp();
909
88.1k
}
910
911
912
#if d_m3HasStackSwitching
913
914
d_m3Op(Branch);
915
d_m3Op(Entry);
916
#  if !d_m3EntryKeepsFrame
917
d_m3Op(Entry_Suspendable);
918
#  endif
919
920
// The function a body of compiled code belongs to. op_Call is handed the code
921
// rather than the function, but every body opens with op_Entry and the function
922
// it enters - past a bridge, where the page ran out before the first op.
923
static M3_NOINLINE
924
IM3Function FunctionOfCompiledCode (pc_t i_pc)
925
0
{
926
0
    if (not i_pc) {
927
0
        return NULL;
928
0
    }
929
930
0
    while ((IM3Operation)i_pc[0] == op_Branch) {
931
0
        i_pc = (pc_t)i_pc[1];
932
0
    }
933
934
0
    IM3Operation entry = (IM3Operation)i_pc[0];
935
936
0
#  if !d_m3EntryKeepsFrame
937
0
    if (entry == op_Entry_Suspendable) {
938
0
        return (IM3Function)i_pc[1];
939
0
    }
940
0
#  endif
941
0
    return (entry == op_Entry) ? (IM3Function)i_pc[1] : NULL;
942
0
}
943
944
#endif
945
946
d_m3Op(Call)
947
132k
{
948
132k
    d_m3CheckNativeStack();
949
950
132k
    pc_t      callPC = immediate(pc_t);
951
132k
    i32       stackOffset = immediate(i32);
952
132k
    IM3Memory memory = m3MemInfo(_mem);
953
954
132k
    m3stack_t sp = _sp + stackOffset;
955
956
#if (d_m3EnableOpProfiling || d_m3EnableOpTracing)
957
    m3ret_t r = Call(callPC, sp, _mem, d_m3OpDefaultArgs, d_m3BaseCstr);
958
#else
959
132k
    m3ret_t r = Call(callPC, sp, _mem, d_m3OpDefaultArgs);
960
132k
#endif
961
962
132k
    _mem = memory->mallocated;
963
964
132k
    if (M3_LIKELY(not r)) {
965
583
        nextOp();
966
132k
    } else {
967
132k
        d_m3RecordCallFrame(memory, FunctionOfCompiledCode(callPC));
968
132k
        pushBacktraceFrame();
969
132k
        forwardTrap(r);
970
132k
    }
971
132k
}
972
973
974
// call_ref / return_call_ref: like the indirect calls, except the callee comes
975
// straight off the stack instead of out of a table, so there is no bounds check
976
// and no index. The type still has to match: a (ref null $t) can hold a
977
// reference the validator only knows as $t, and null has to trap.
978
d_m3Op(CallRef)
979
405
{
980
405
    IM3Function function = slot(IM3Function);
981
405
    IM3FuncType type = immediate(IM3FuncType);
982
405
    i32         stackOffset = immediate(i32);
983
405
    IM3Memory   memory = m3MemInfo(_mem);
984
985
405
    m3stack_t   sp = _sp + stackOffset;
986
987
405
    m3ret_t     r = m3Err_none;
988
989
405
    if (M3_LIKELY(function)) {
990
402
        if (M3_LIKELY(type == function->funcType)) {
991
402
            if (M3_UNLIKELY(not function->compiled)) {
992
0
                r = CompileFunction(function);
993
0
            }
994
995
402
            if (M3_LIKELY(not r)) {
996
#if (d_m3EnableOpProfiling || d_m3EnableOpTracing)
997
                r = Call(function->compiled, sp, _mem, d_m3OpDefaultArgs, d_m3BaseCstr);
998
#else
999
402
                r = Call(function->compiled, sp, _mem, d_m3OpDefaultArgs);
1000
402
#endif
1001
1002
402
                _mem = memory->mallocated;
1003
1004
402
                if (M3_LIKELY(not r)) {
1005
0
                    nextOpDirect();
1006
402
                } else {
1007
402
                    d_m3RecordCallFrame(memory, function);
1008
402
                    pushBacktraceFrame();
1009
402
                    forwardTrap(r);
1010
402
                }
1011
402
            }
1012
402
        } else {
1013
0
            r = m3Err_trapIndirectCallTypeMismatch;
1014
0
        }
1015
402
    } else {
1016
3
        r = m3Err_trapNullFunctionRef;
1017
3
    }
1018
1019
3
    if (M3_UNLIKELY(r)) {
1020
3
        newTrap(r);
1021
3
    } else {
1022
0
        forwardTrap(r);
1023
0
    }
1024
3
}
1025
1026
1027
// ref.as_non_null is a null check and nothing else: the value stays put, so
1028
// there is no destination slot, only the trap.
1029
d_m3Op(RefAsNonNull)
1030
1.15k
{
1031
1.15k
    IM3Function reference = slot(IM3Function);
1032
1033
1.15k
    if (M3_UNLIKELY(not reference)) {
1034
11
        newTrap(m3Err_trapNullReference);
1035
11
    }
1036
1037
1.15k
    nextOp();
1038
1.15k
}
1039
1040
1041
d_m3Op(CallIndirect)
1042
50
{
1043
50
    d_m3CheckNativeStack();
1044
1045
50
    M3Table*    table = immediate(M3Table*);
1046
50
    u64         tableIndex = d_m3WideOperand(table->isTable64);
1047
50
    IM3FuncType type = immediate(IM3FuncType);
1048
50
    i32         stackOffset = immediate(i32);
1049
50
    IM3Memory   memory = m3MemInfo(_mem);
1050
1051
50
    m3stack_t   sp = _sp + stackOffset;
1052
1053
50
    m3ret_t     r = m3Err_none;
1054
1055
50
    if (M3_LIKELY(tableIndex < table->size)) {
1056
12
        IM3Function function = (IM3Function)table->elements[tableIndex];
1057
1058
12
        if (M3_LIKELY(function)) {
1059
4
            if (M3_LIKELY(type == function->funcType)) {
1060
3
                if (M3_UNLIKELY(not function->compiled)) {
1061
3
                    r = CompileFunction(function);
1062
3
                }
1063
1064
3
                if (M3_LIKELY(not r)) {
1065
                    // a table may hold functions from another module, and those
1066
                    // run against their own module's memory
1067
2
                    M3MemoryHeader* calleeMem = Module_MemoryHeader(function->module);
1068
1069
#if (d_m3EnableOpProfiling || d_m3EnableOpTracing)
1070
                    r = Call(function->compiled, sp, calleeMem, d_m3OpDefaultArgs, d_m3BaseCstr);
1071
#else
1072
2
                    r = Call(function->compiled, sp, calleeMem, d_m3OpDefaultArgs);
1073
2
#endif
1074
1075
2
                    _mem = memory->mallocated;
1076
1077
2
                    if (M3_LIKELY(not r)) {
1078
1
                        nextOpDirect();
1079
1
                    } else {
1080
1
                        d_m3RecordCallFrame(memory, function);
1081
1
                        pushBacktraceFrame();
1082
1
                        forwardTrap(r);
1083
1
                    }
1084
2
                }
1085
3
            } else {
1086
1
                r = m3Err_trapIndirectCallTypeMismatch;
1087
1
            }
1088
8
        } else {
1089
8
            r = m3Err_trapTableElementIsNull;
1090
8
        }
1091
38
    } else {
1092
38
        r = m3Err_trapTableIndexOutOfRange;
1093
38
    }
1094
1095
48
    if (M3_UNLIKELY(r)) {
1096
48
        newTrap(r);
1097
48
    } else {
1098
0
        forwardTrap(r);
1099
0
    }
1100
48
}
1101
1102
1103
// return_call / return_call_indirect: the callee takes over this function's stack frame
1104
// instead of getting one of its own.  The spec guarantees the callee returns exactly what
1105
// the enclosing function returns, so the two frames share their return slots and only the
1106
// arguments have to be relocated: the compiler stages them above the caller's stack (they
1107
// can still read the args/locals they're about to overwrite) and the op slides them down
1108
// onto the frame base.  The jump is a tail call, so neither the m3 stack nor the native
1109
// stack grows.  Tail recursion therefore runs in constant space, unless the return_call
1110
// sits inside a loop or a try region: those hold a native frame that the tail call walks
1111
// away from instead of unwinding, and d_m3CheckNativeStack bounds the pile they make.
1112
#define d_m3TailCallArgs(RETURNSLOTS, STACKOFFSET, NUMARGSLOTS)                     \
1113
179M
   memmove ((void *) (_sp + (RETURNSLOTS)), (const void *) (_sp + (STACKOFFSET)),   \
1114
179M
            (size_t) (NUMARGSLOTS) * sizeof (m3slot_t))
1115
1116
d_m3Op(ReturnCall)
1117
179M
{
1118
179M
    pc_t    callPC = immediate(pc_t);
1119
179M
    i32     stackOffset = immediate(i32);
1120
179M
    i32     returnSlots = immediate(i32);
1121
179M
    u32     numArgSlots = immediate(u32);
1122
1123
179M
    m3ret_t possible_trap = m3_Yield();
1124
179M
    if (M3_UNLIKELY(possible_trap)) {
1125
0
        newTrap(possible_trap);
1126
0
    }
1127
1128
179M
    d_m3TailCallArgs(returnSlots, stackOffset, numArgSlots);
1129
1130
179M
    jumpOpDirect(callPC);
1131
179M
}
1132
1133
1134
d_m3Op(ReturnCallRef)
1135
1.91k
{
1136
1.91k
    IM3Function function = slot(IM3Function);
1137
1.91k
    IM3FuncType type = immediate(IM3FuncType);
1138
1.91k
    i32         stackOffset = immediate(i32);
1139
1.91k
    i32         returnSlots = immediate(i32);
1140
1.91k
    u32         numArgSlots = immediate(u32);
1141
1142
1.91k
    m3ret_t     r = m3Err_none;
1143
1144
1.91k
    if (M3_LIKELY(function)) {
1145
1.89k
        if (M3_LIKELY(type == function->funcType)) {
1146
1.89k
            if (M3_UNLIKELY(not function->compiled)) {
1147
0
                r = CompileFunction(function);
1148
0
            }
1149
1150
1.89k
            if (M3_LIKELY(not r)) {
1151
1.89k
                r = m3_Yield();
1152
1153
1.89k
                if (M3_LIKELY(not r)) {
1154
1.89k
                    d_m3TailCallArgs(returnSlots, stackOffset, numArgSlots);
1155
1156
1.89k
                    jumpOpDirect(function->compiled);
1157
1.89k
                }
1158
1.89k
            }
1159
1.89k
        } else {
1160
0
            r = m3Err_trapIndirectCallTypeMismatch;
1161
0
        }
1162
1.89k
    } else {
1163
24
        r = m3Err_trapNullFunctionRef;
1164
24
    }
1165
1166
1.91k
    newTrap(r);
1167
1.91k
}
1168
1169
1170
d_m3Op(ReturnCallIndirect)
1171
45
{
1172
45
    M3Table*    table = immediate(M3Table*);
1173
45
    u64         tableIndex = d_m3WideOperand(table->isTable64);
1174
45
    IM3FuncType type = immediate(IM3FuncType);
1175
45
    i32         stackOffset = immediate(i32);
1176
45
    i32         returnSlots = immediate(i32);
1177
45
    u32         numArgSlots = immediate(u32);
1178
1179
45
    m3ret_t     r = m3Err_none;
1180
1181
45
    if (M3_LIKELY(tableIndex < table->size)) {
1182
7
        IM3Function function = (IM3Function)table->elements[tableIndex];
1183
1184
7
        if (M3_LIKELY(function)) {
1185
3
            if (M3_LIKELY(type == function->funcType)) {
1186
2
                if (M3_UNLIKELY(not function->compiled)) {
1187
2
                    r = CompileFunction(function);
1188
2
                }
1189
1190
2
                if (M3_LIKELY(not r)) {
1191
1
                    r = m3_Yield();
1192
1193
1
                    if (M3_LIKELY(not r)) {
1194
1
                        d_m3TailCallArgs(returnSlots, stackOffset, numArgSlots);
1195
1196
1
                        jumpOpDirect(function->compiled);
1197
1
                    }
1198
1
                }
1199
2
            } else {
1200
1
                r = m3Err_trapIndirectCallTypeMismatch;
1201
1
            }
1202
4
        } else {
1203
4
            r = m3Err_trapTableElementIsNull;
1204
4
        }
1205
38
    } else {
1206
38
        r = m3Err_trapTableIndexOutOfRange;
1207
38
    }
1208
1209
45
    newTrap(r);
1210
45
}
1211
1212
1213
d_m3Op(CallRawFunction)
1214
0
{
1215
0
    d_m3TracePrepare
1216
1217
0
    M3ImportContext ctx;
1218
1219
0
    M3RawCall       call = (M3RawCall)(*_pc++);
1220
0
    ctx.function = immediate(IM3Function);
1221
0
    ctx.userdata = immediate(void*);
1222
0
    u64* const sp = ((u64*)_sp);
1223
0
    IM3Memory  memory = m3MemInfo(_mem);
1224
1225
0
    IM3Runtime runtime = m3MemRuntime(_mem);
1226
1227
#if d_m3EnableStrace
1228
    IM3FuncType ftype = ctx.function->funcType;
1229
1230
    char        outbuff[1024];
1231
    char*       outp = outbuff;
1232
    char*       oute = outbuff + 1024;
1233
1234
    outp += snprintf(outp, oute - outp, "%s!%s(", ctx.function->import.moduleUtf8, ctx.function->import.fieldUtf8);
1235
1236
    const int nArgs = ftype->numArgs;
1237
    const int nRets = ftype->numRets;
1238
    u64*      args = sp + nRets;
1239
    for (int i = 0; i < nArgs; i++) {
1240
        const int type = ftype->types[nRets + i];
1241
        switch (type) {
1242
        case c_m3Type_i32: outp += snprintf(outp, oute - outp, "%" PRIi32, *(i32*)(args + i)); break;
1243
        case c_m3Type_i64: outp += snprintf(outp, oute - outp, "%" PRIi64, *(i64*)(args + i)); break;
1244
        case c_m3Type_f32: outp += snprintf(outp, oute - outp, "%" PRIf32, *(f32*)(args + i)); break;
1245
        case c_m3Type_f64: outp += snprintf(outp, oute - outp, "%" PRIf64, *(f64*)(args + i)); break;
1246
        default: outp += snprintf(outp, oute - outp, "<type %d>", type); break;
1247
        }
1248
        if (i < nArgs - 1) {
1249
            outp += snprintf(outp, oute - outp, ", ");
1250
        }
1251
    }
1252
    // closed here rather than after the last argument: an import taking none has
1253
    // no last argument to close it
1254
    outp += snprintf(outp, oute - outp, ")");
1255
#  if d_m3EnableStrace >= 2
1256
    outp += snprintf(outp, oute - outp, " { <native> }");
1257
#  endif
1258
#endif
1259
1260
    // m3_Call uses runtime->stack to set-up initial exported function stack.
1261
    // Reconfigure the stack to enable recursive invocations of m3_Call.
1262
    // I.e. exported/table function can be called from an impoted function.
1263
0
    void* stack_backup = runtime->stack;
1264
0
    runtime->stack = sp;
1265
    // the memory this import was bound to, which is memory 0 unless the host
1266
    // module named another one. _mem itself stays on the caller's memory:
1267
    // the trap path below and the backtrace recorder still read it.
1268
0
    m3ret_t possible_trap = call(runtime, &ctx, sp, m3MemData(ctx.function->hostMemory->mallocated));
1269
0
    runtime->stack = stack_backup;
1270
1271
#if d_m3EnableStrace
1272
    if (M3_UNLIKELY(possible_trap)) {
1273
        d_m3TracePrint("%s -> %s", outbuff, (char*)possible_trap);
1274
    } else if (ftype and ftype->numRets) {
1275
        d_m3TracePrint("%s = %s", outbuff, SPrintFunctionRetList(ftype, (m3stack_t)sp));
1276
    } else {
1277
        d_m3TracePrint("%s", outbuff);
1278
    }
1279
#endif
1280
1281
0
    if (M3_UNLIKELY(possible_trap)) {
1282
0
        _mem = memory->mallocated;
1283
        // an exception the host threw (m3_ThrowException) is not a trap yet, and
1284
        // may well be caught: it records no frame, as a Wasm throw doesn't
1285
0
        if (possible_trap != m3Err_pendingException) {
1286
0
            pushBacktraceFrame();
1287
0
        }
1288
0
    }
1289
0
    forwardTrap(possible_trap);
1290
0
}
1291
1292
1293
d_m3Op(MemSize)
1294
2.55M
{
1295
2.55M
    IM3Memory memory = m3MemInfo(_mem);
1296
1297
2.55M
    _r0 = memory->numPages;
1298
1299
2.55M
    nextOp();
1300
2.55M
}
1301
1302
1303
d_m3Op(MemGrow)
1304
52.1k
{
1305
52.1k
    IM3Runtime runtime = m3MemRuntime(_mem);
1306
52.1k
    IM3Memory  memory = m3MemInfo(_mem);
1307
1308
52.1k
    i32        numPagesToGrow = (i32)_r0;
1309
52.1k
    if (numPagesToGrow >= 0) {
1310
46.7k
        _r0 = (m3reg_t)memory->numPages;
1311
1312
46.7k
        if (M3_LIKELY(numPagesToGrow)) {
1313
29.9k
            u64      requiredPages = memory->numPages + (u32)numPagesToGrow;
1314
1315
29.9k
            M3Result r = ResizeMemory(runtime, memory, requiredPages);
1316
29.9k
            if (r) {
1317
4.32k
                _r0 = -1;
1318
4.32k
            }
1319
1320
29.9k
            _mem = memory->mallocated;
1321
29.9k
        }
1322
46.7k
    } else {
1323
5.35k
        _r0 = -1;
1324
5.35k
    }
1325
1326
52.1k
    nextOp();
1327
52.1k
}
1328
1329
1330
#if d_m3HasMemory64
1331
1332
// memory.grow on a 64-bit memory. The delta is a full u64 rather than a value
1333
// the sign of which can stand in for "too big", and failure answers 2^64-1
1334
// instead of 2^32-1 - which is the same -1 in the register, sized by the slot
1335
// it is written to.
1336
d_m3Op(MemGrow64)
1337
31.2k
{
1338
31.2k
    IM3Runtime runtime = m3MemRuntime(_mem);
1339
31.2k
    IM3Memory  memory = m3MemInfo(_mem);
1340
1341
31.2k
    u64        numPagesToGrow = (u64)_r0;
1342
31.2k
    u64        numPages = memory->numPages;
1343
1344
31.2k
    if (M3_LIKELY(numPagesToGrow)) {
1345
        // maxPages is never below the current size, so the difference cannot
1346
        // wrap; asking for more than it is a request nothing could satisfy
1347
25.1k
        if (numPagesToGrow <= memory->maxPages - numPages and
1348
19.1k
            not ResizeMemory(runtime, memory, numPages + numPagesToGrow)) {
1349
13.9k
            _r0 = (m3reg_t)numPages;
1350
13.9k
        } else {
1351
11.1k
            _r0 = -1;
1352
11.1k
        }
1353
1354
25.1k
        _mem = memory->mallocated;
1355
25.1k
    } else {
1356
6.07k
        _r0 = (m3reg_t)numPages;
1357
6.07k
    }
1358
1359
31.2k
    nextOp();
1360
31.2k
}
1361
1362
#endif // d_m3HasMemory64
1363
1364
1365
d_m3Op(MemCopy)
1366
1.19k
{
1367
1.19k
    u64 size = (u32)_r0;
1368
1.19k
    u64 source = slot(u32);
1369
1.19k
    u64 destination = slot(u32);
1370
1371
1.19k
    if (M3_LIKELY(d_m3MemRangeOk(destination, size, _mem))) {
1372
1.19k
        if (M3_LIKELY(d_m3MemRangeOk(source, size, _mem))) {
1373
1.19k
            u8* dst = m3MemData(_mem) + destination;
1374
1.19k
            u8* src = m3MemData(_mem) + source;
1375
1.19k
            memmove(dst, src, (size_t)size);
1376
1377
1.19k
            nextOp();
1378
1.19k
        } else {
1379
6
            d_outOfBoundsMemOp(source, size);
1380
6
        }
1381
1.19k
    } else {
1382
3
        d_outOfBoundsMemOp(destination, size);
1383
3
    }
1384
1.19k
}
1385
1386
1387
#if d_m3HasMemory64
1388
1389
// memory.copy within a single 64-bit memory: every operand is a full u64.
1390
d_m3Op(MemCopy64)
1391
3.23k
{
1392
3.23k
    u64 size = (u64)_r0;
1393
3.23k
    u64 source = slot(u64);
1394
3.23k
    u64 destination = slot(u64);
1395
1396
3.23k
    if (M3_LIKELY(d_m3MemRangeOk(destination, size, _mem))) {
1397
3.07k
        if (M3_LIKELY(d_m3MemRangeOk(source, size, _mem))) {
1398
2.99k
            u8* dst = m3MemData(_mem) + destination;
1399
2.99k
            u8* src = m3MemData(_mem) + source;
1400
2.99k
            memmove(dst, src, (size_t)size);
1401
1402
2.99k
            nextOp();
1403
2.99k
        } else {
1404
77
            d_outOfBoundsMemOp(source, size);
1405
77
        }
1406
3.07k
    } else {
1407
154
        d_outOfBoundsMemOp(destination, size);
1408
154
    }
1409
3.23k
}
1410
1411
#endif // d_m3HasMemory64
1412
1413
1414
// Points the _mem register at another memory: one of the module's own, or
1415
// memory 0 of a module being called into. The compiler emits these in pairs,
1416
// around a single access or a single cross-module call, so _mem is back where
1417
// it belongs before anything that reads it for another purpose - a backtrace,
1418
// the stack-limit check - can run.
1419
d_m3Op(SetMemory)
1420
72.5k
{
1421
72.5k
    IM3Memory memory = immediate(IM3Memory);
1422
1423
72.5k
    _mem = memory->mallocated;
1424
1425
72.5k
    nextOp();
1426
72.5k
}
1427
1428
1429
#if d_m3HasMultiMemory
1430
1431
// memory.copy between two different memories. The pair-of-SetMemory trick only
1432
// reaches one memory at a time, so this one names both outright.
1433
//
1434
// The two need not be addressed the same way, so each operand's width comes
1435
// from the memory it belongs to: bit 0 of the widths immediate for the
1436
// destination, bit 1 for the source. The length follows the narrower of the
1437
// two, which is 64-bit only when both are.
1438
d_m3Op(MemCopy_x)
1439
2.51k
{
1440
2.51k
    IM3Memory       destMemory = immediate(IM3Memory);
1441
2.51k
    IM3Memory       sourceMemory = immediate(IM3Memory);
1442
2.51k
    u32             widths = immediate(u32);
1443
1444
2.51k
    M3MemoryHeader* destMem = destMemory->mallocated;
1445
2.51k
    M3MemoryHeader* sourceMem = sourceMemory->mallocated;
1446
1447
2.51k
    u64             size = (widths == 0x3) ? (u64)_r0 : (u64)(u32)_r0;
1448
2.51k
    u64             source = d_m3WideOperand(widths & 0x2);
1449
2.51k
    u64             destination = d_m3WideOperand(widths & 0x1);
1450
1451
2.51k
    if (M3_LIKELY(d_m3MemRangeOk(destination, size, destMem))) {
1452
2.44k
        if (M3_LIKELY(d_m3MemRangeOk(source, size, sourceMem))) {
1453
2.41k
            memmove(m3MemData(destMem) + destination, m3MemData(sourceMem) + source, (size_t)size);
1454
1455
2.41k
            nextOp();
1456
2.41k
        } else {
1457
23
            d_outOfBoundsMemOp(source, size);
1458
23
        }
1459
2.44k
    } else {
1460
77
        d_outOfBoundsMemOp(destination, size);
1461
77
    }
1462
2.51k
}
1463
1464
#endif // d_m3HasMultiMemory
1465
1466
1467
d_m3Op(MemFill)
1468
3.78k
{
1469
3.78k
    u32 size = (u32)_r0;
1470
3.78k
    u32 byte = slot(u32);
1471
3.78k
    u64 destination = slot(u32);
1472
1473
3.78k
    if (M3_LIKELY(d_m3MemRangeOk(destination, size, _mem))) {
1474
3.75k
        u8* mem8 = m3MemData(_mem) + destination;
1475
3.75k
        memset(mem8, (u8)byte, size);
1476
3.75k
        nextOp();
1477
3.75k
    } else {
1478
27
        d_outOfBoundsMemOp(destination, size);
1479
27
    }
1480
3.78k
}
1481
1482
1483
#if d_m3HasMemory64
1484
1485
// memory.fill on a 64-bit memory. The byte to write stays an i32 - it is a
1486
// value, not an address - so only the destination and the length widen.
1487
d_m3Op(MemFill64)
1488
1.16k
{
1489
1.16k
    u64 size = (u64)_r0;
1490
1.16k
    u32 byte = slot(u32);
1491
1.16k
    u64 destination = slot(u64);
1492
1493
1.16k
    if (M3_LIKELY(d_m3MemRangeOk(destination, size, _mem))) {
1494
1.09k
        u8* mem8 = m3MemData(_mem) + destination;
1495
1.09k
        memset(mem8, (u8)byte, (size_t)size);
1496
1.09k
        nextOp();
1497
1.09k
    } else {
1498
73
        d_outOfBoundsMemOp(destination, size);
1499
73
    }
1500
1.16k
}
1501
1502
#endif // d_m3HasMemory64
1503
1504
1505
d_m3Op(MemInit)
1506
0
{
1507
0
    M3DataSegment* segment = immediate(M3DataSegment*);
1508
1509
0
    u64            size = (u32)_r0;
1510
0
    u64            source = slot(u32);
1511
0
    u64            destination = slot(u32);
1512
1513
0
    u64            available = segment->dropped ? 0 : segment->size;
1514
1515
0
    if (M3_LIKELY(d_m3MemRangeOk(destination, size, _mem))) {
1516
0
        if (M3_LIKELY(source <= available and size <= available - source)) {
1517
0
            memcpy(m3MemData(_mem) + destination, segment->data + source, (size_t)size);
1518
0
            nextOp();
1519
0
        } else {
1520
0
            d_outOfBoundsMemOp(source, size);
1521
0
        }
1522
0
    } else {
1523
0
        d_outOfBoundsMemOp(destination, size);
1524
0
    }
1525
0
}
1526
1527
1528
#if d_m3HasMemory64
1529
1530
// memory.init into a 64-bit memory. The segment is indexed as an i32 whatever
1531
// the memory is, so only the destination widens.
1532
d_m3Op(MemInit64)
1533
0
{
1534
0
    M3DataSegment* segment = immediate(M3DataSegment*);
1535
1536
0
    u64            size = (u32)_r0;
1537
0
    u64            source = slot(u32);
1538
0
    u64            destination = slot(u64);
1539
1540
0
    u64            available = segment->dropped ? 0 : segment->size;
1541
1542
0
    if (M3_LIKELY(d_m3MemRangeOk(destination, size, _mem))) {
1543
0
        if (M3_LIKELY(source <= available and size <= available - source)) {
1544
0
            memcpy(m3MemData(_mem) + destination, segment->data + source, (size_t)size);
1545
0
            nextOp();
1546
0
        } else {
1547
0
            d_outOfBoundsMemOp(source, size);
1548
0
        }
1549
0
    } else {
1550
0
        d_outOfBoundsMemOp(destination, size);
1551
0
    }
1552
0
}
1553
1554
#endif // d_m3HasMemory64
1555
1556
1557
d_m3Op(DataDrop)
1558
0
{
1559
0
    M3DataSegment* segment = immediate(M3DataSegment*);
1560
0
    segment->dropped = true;
1561
1562
0
    nextOp();
1563
0
}
1564
1565
1566
#if d_m3HasRefTypes
1567
1568
d_m3Op(TableGet)
1569
140k
{
1570
140k
    M3Table* table = immediate(M3Table*);
1571
140k
    u64      index = d_m3WideOperand(table->isTable64);
1572
1573
140k
    if (M3_LIKELY(index < table->size)) {
1574
140k
        _r0 = (u64)(uintptr_t)table->elements[index];
1575
140k
        nextOp();
1576
140k
    } else {
1577
104
        newTrap(m3Err_trapTableOutOfBounds);
1578
104
    }
1579
140k
}
1580
1581
1582
d_m3Op(TableSet)
1583
89.0k
{
1584
89.0k
    M3Table* table = immediate(M3Table*);
1585
89.0k
    void*    value = slot(void*);
1586
89.0k
    u64      index = d_m3WideOperand(table->isTable64);
1587
1588
89.0k
    if (M3_LIKELY(index < table->size)) {
1589
89.0k
        table->elements[index] = value;
1590
89.0k
        nextOp();
1591
89.0k
    } else {
1592
8
        newTrap(m3Err_trapTableOutOfBounds);
1593
8
    }
1594
89.0k
}
1595
1596
1597
d_m3Op(TableSize)
1598
90.3k
{
1599
90.3k
    M3Table* table = immediate(M3Table*);
1600
1601
90.3k
    _r0 = table->size;
1602
1603
90.3k
    nextOp();
1604
90.3k
}
1605
1606
1607
d_m3Op(TableGrow)
1608
10.5k
{
1609
10.5k
    M3Table* table = immediate(M3Table*);
1610
10.5k
    u64      delta = d_m3WideOperand(table->isTable64);
1611
10.5k
    void*    value = slot(void*);
1612
1613
10.5k
    u32      oldSize = table->size;
1614
10.5k
    u32      maxSize = table->maxSize ? table->maxSize : d_m3MaxSaneTableSize;
1615
1616
    // a table64 delta is a whole u64, so the sum is formed only once it is
1617
    // known to fit
1618
10.5k
    u64      newSize = (delta <= maxSize - oldSize) ? (u64)oldSize + delta
1619
10.5k
                                                    : (u64)maxSize + 1;
1620
1621
10.5k
    if (newSize == oldSize)         // a zero delta never reallocates, and the table may have no storage yet
1622
309
    {
1623
309
        _r0 = oldSize;
1624
309
        nextOp();
1625
309
    }
1626
1627
10.2k
    IM3Runtime runtime = m3MemRuntime(_mem);
1628
10.2k
    if (newSize <= maxSize and (not runtime->tableElementsLimit or
1629
7.44k
                                delta <= runtime->tableElementsLimit - runtime->tableElementsUsed)) {
1630
5.85k
        void** elements = m3_ReallocArray(void*, table->elements, (size_t)newSize, oldSize);
1631
1632
5.85k
        if (elements) {
1633
5.85k
            runtime->tableElementsUsed += newSize - oldSize;
1634
5.85k
            table->elements = elements;
1635
5.85k
            table->size = (u32)newSize;
1636
1637
17.9M
            for (u32 i = oldSize; i < table->size; ++i) {
1638
17.9M
                table->elements[i] = value;
1639
17.9M
            }
1640
1641
5.85k
            _r0 = oldSize;
1642
5.85k
            nextOp();
1643
5.85k
        }
1644
5.85k
    }
1645
1646
    // spec: a failed grow returns -1 - which for a table64 is 2^64-1, and the
1647
    // slot it is pushed to is what decides how much of the register is seen
1648
4.36k
    _r0 = -1;
1649
1650
4.36k
    nextOp();
1651
10.2k
}
1652
1653
1654
d_m3Op(TableInit)
1655
2.12k
{
1656
2.12k
    M3Table*          table = immediate(M3Table*);
1657
2.12k
    M3ElementSegment* segment = immediate(M3ElementSegment*);
1658
2.12k
    u32               count = slot(u32);
1659
2.12k
    u32               source = slot(u32);
1660
    // an element segment is indexed as an i32 whatever the table is; only the
1661
    // destination follows the table's index type
1662
2.12k
    u64               destination = d_m3WideOperand(table->isTable64);
1663
1664
2.12k
    u64               available = segment->dropped ? 0 : segment->numElements;
1665
1666
2.12k
    if (M3_LIKELY(destination <= table->size and count <= table->size - destination and
1667
2.12k
                  (u64) source + count <= available)) {
1668
2.11k
        for (u32 i = 0; i < count; ++i) {
1669
0
            table->elements[destination + i] = segment->resolved[source + i];
1670
0
        }
1671
1672
2.11k
        nextOp();
1673
2.11k
    } else {
1674
6
        newTrap(m3Err_trapTableOutOfBounds);
1675
6
    }
1676
2.12k
}
1677
1678
1679
d_m3Op(ElemDrop)
1680
232k
{
1681
232k
    M3ElementSegment* segment = immediate(M3ElementSegment*);
1682
232k
    segment->dropped = true;
1683
1684
232k
    nextOp();
1685
232k
}
1686
1687
1688
d_m3Op(TableCopy)
1689
3.19k
{
1690
3.19k
    M3Table* dst = immediate(M3Table*);
1691
3.19k
    M3Table* src = immediate(M3Table*);
1692
    // the length follows the narrower of the two tables, so it is 64-bit only
1693
    // when both are
1694
3.19k
    u64      count = d_m3WideOperand(dst->isTable64 and src->isTable64);
1695
3.19k
    u64      source = d_m3WideOperand(src->isTable64);
1696
3.19k
    u64      destination = d_m3WideOperand(dst->isTable64);
1697
1698
3.19k
    if (M3_LIKELY(destination <= dst->size and count <= dst->size - destination and
1699
3.19k
                  source <= src->size and count <= src->size - source)) {
1700
2.99k
        memmove(dst->elements + destination, src->elements + source, (size_t)count * sizeof(void*));
1701
1702
2.99k
        nextOp();
1703
2.99k
    } else {
1704
193
        newTrap(m3Err_trapTableOutOfBounds);
1705
193
    }
1706
3.19k
}
1707
1708
1709
d_m3Op(TableFill)
1710
4.94k
{
1711
4.94k
    M3Table* table = immediate(M3Table*);
1712
4.94k
    u64      count = d_m3WideOperand(table->isTable64);
1713
4.94k
    void*    value = slot(void*);
1714
4.94k
    u64      index = d_m3WideOperand(table->isTable64);
1715
1716
4.94k
    if (M3_LIKELY(index <= table->size and count <= table->size - index)) {
1717
107k
        for (u64 i = 0; i < count; ++i) {
1718
102k
            table->elements[index + i] = value;
1719
102k
        }
1720
1721
4.93k
        nextOp();
1722
4.93k
    } else {
1723
9
        newTrap(m3Err_trapTableOutOfBounds);
1724
9
    }
1725
4.94k
}
1726
1727
#endif // d_m3HasRefTypes
1728
1729
1730
// it's a debate: should the compilation be trigger be the caller or callee page.
1731
// it's a much easier to put it in the caller pager. if it's in the callee, either the entire page
1732
// has be left dangling or it's just a stub that jumps to a newly acquired page.  In Gestalt, I opted
1733
// for the stub approach. Stubbing makes it easier to dynamically free the compilation. You can also
1734
// do both.
1735
d_m3Op(Compile)
1736
6.39k
{
1737
6.39k
    rewrite_op(op_Call);
1738
1739
6.39k
    IM3Function function = immediate(IM3Function);
1740
1741
6.39k
    m3ret_t     result = m3Err_none;
1742
1743
6.39k
    if (M3_UNLIKELY(not function->compiled)) { // check to see if function was compiled since this operation was emitted.
1744
103
        result = CompileFunction(function);
1745
103
    }
1746
1747
6.39k
    if (not result) {
1748
        // patch up compiled pc and call rewritten op_Call
1749
6.38k
        *((void**)--_pc) = (void*)(function->compiled);
1750
6.38k
        --_pc;
1751
6.38k
        nextOpDirect();
1752
6.38k
    }
1753
1754
6.39k
    newTrap(result);
1755
6.39k
}
1756
1757
1758
// same as op_Compile, for a call site that was emitted as a tail call
1759
d_m3Op(CompileReturnCall)
1760
8.65k
{
1761
8.65k
    rewrite_op(op_ReturnCall);
1762
1763
8.65k
    IM3Function function = immediate(IM3Function);
1764
1765
8.65k
    m3ret_t     result = m3Err_none;
1766
1767
8.65k
    if (M3_UNLIKELY(not function->compiled)) {
1768
21
        result = CompileFunction(function);
1769
21
    }
1770
1771
8.65k
    if (not result) {
1772
        // patch up compiled pc and call rewritten op_ReturnCall
1773
8.65k
        *((void**)--_pc) = (void*)(function->compiled);
1774
8.65k
        --_pc;
1775
8.65k
        nextOpDirect();
1776
8.65k
    }
1777
1778
8.65k
    newTrap(result);
1779
8.65k
}
1780
1781
1782
#if d_m3HasStackSwitching
1783
// Suspending for a reason that is not a control tag - the host asked, or the
1784
// gas ran out. There is no handler to look for and no payload to carry, and
1785
// clearing the routing a previous suspend left behind is what keeps this from
1786
// being mistaken for one: a resume reads those fields to decide where to send
1787
// the marker, and would otherwise send this one into whatever stub was last
1788
// used, with whatever payload last went with it.
1789
//
1790
// No continuation handles it either. A resume that finds itself named as the
1791
// handler takes the suspend as its own, so naming the suspending continuation
1792
// would stop a suspend from inside a resumed one at that resume, with no stub
1793
// to run. Naming none sends it through every resume up to the host.
1794
static
1795
void SuspendWithoutTag (IM3Runtime io_runtime, IM3Continuation io_cont, M3SafePointKind i_kind,
1796
                        pc_t i_pc, m3stack_t i_sp, m3reg_t i_r0
1797
#  if d_m3HasFloat
1798
                        ,
1799
                        f64 i_fp0
1800
#  endif
1801
)
1802
0
{
1803
0
    io_runtime->suspendRequested = false;
1804
1805
0
    io_runtime->suspendTag = NULL;
1806
0
    io_runtime->suspendHandlerCont = NULL;
1807
0
    io_runtime->suspendStubPC = NULL;
1808
0
    io_runtime->switchTarget = NULL;
1809
0
    io_runtime->numSuspendPayload = 0;
1810
1811
0
    io_cont->pc = i_pc;
1812
0
    io_cont->suspendPoint = (u8)i_kind;
1813
0
    io_cont->sp = i_sp;
1814
0
    io_cont->r0 = i_r0;
1815
0
#  if d_m3HasFloat
1816
0
    io_cont->fp0 = i_fp0;
1817
0
#  endif
1818
1819
0
    io_cont->numSuspendResults = 0;
1820
0
}
1821
#endif // d_m3HasStackSwitching
1822
1823
1824
#if d_m3HasGasMetering
1825
1826
// Pays for the straight-line segment of the function body that follows, before
1827
// any of it runs. The compiler adds up the segment's instruction costs while it
1828
// compiles them and leaves the total here as an immediate, so metering costs one
1829
// subtract and one branch however long the segment is.
1830
//
1831
// The counter is allowed to go negative - the segment was charged in full - and
1832
// nothing resets it, so the trap stands until the host arms the runtime again.
1833
d_m3Op(UseGas)
1834
289M
{
1835
289M
    IM3Runtime runtime = m3MemRuntime(_mem);
1836
289M
    u32        cost = immediate(u32);
1837
1838
289M
    runtime->gasRemaining -= (i64)cost;
1839
1840
289M
    if (M3_UNLIKELY(runtime->gasRemaining < 0)) {
1841
8.64k
#  if d_m3HasStackSwitching
1842
        // A runtime that can pause does, at the next pause point: running out
1843
        // is a request to stop, like the host's, and the segment runs on to
1844
        // it. The counter goes below zero by what it takes to get there.
1845
8.64k
        if (runtime->isSuspendable and runtime->activeContinuation) {
1846
0
            runtime->suspendRequested = true;
1847
0
            nextOp();
1848
0
        }
1849
8.64k
#  endif
1850
8.64k
        newTrap(m3Err_trapOutOfGas);
1851
8.64k
    }
1852
1853
289M
    nextOp();
1854
289M
}
1855
1856
#endif // d_m3HasGasMetering
1857
1858
1859
// Whether a function's frame fits the stack it is about to be entered on
1860
static inline
1861
bool EntryFits (IM3Function i_function, m3stack_t _sp, M3MemoryHeader* _mem)
1862
179M
{
1863
#if d_m3SkipStackCheck
1864
    (void)i_function;
1865
    (void)_sp;
1866
    (void)_mem;
1867
    return true;
1868
#elif d_m3HasStackSwitching
1869
179M
    IM3Continuation _act = (_mem ? m3MemRuntime(_mem)->activeContinuation : NULL);
1870
179M
    void*           maxStack = (_act && _act->valStack)
1871
179M
                                 ? (void*)(_act->valStack + _act->numStackSlots)
1872
179M
                                 : (_mem ? _mem->maxStack : (void*)~(uintptr_t)0);
1873
179M
    return M3_LIKELY((void*)(_sp + i_function->maxStackSlots) < maxStack);
1874
#else
1875
    return M3_LIKELY((void*)(_sp + i_function->maxStackSlots) < _mem->maxStack);
1876
#endif
1877
179M
}
1878
1879
// Sets up a function's frame: its locals zeroed, and its constants copied in
1880
static inline
1881
void EnterFrame (IM3Function i_function, m3stack_t _sp)
1882
179M
{
1883
#if defined(DEBUG)
1884
    i_function->hits++;
1885
#endif
1886
179M
    u8* stack = (u8*)((m3slot_t*)_sp + i_function->numRetAndArgSlots);
1887
1888
179M
    memset(stack, 0x0, i_function->numLocalBytes);
1889
179M
    stack += i_function->numLocalBytes;
1890
1891
179M
    if (i_function->constants) {
1892
173M
        memcpy(stack, i_function->constants, i_function->numConstantBytes);
1893
173M
    }
1894
179M
}
1895
1896
1897
d_m3Op(Entry)
1898
179M
{
1899
179M
    d_m3ClearRegisters
1900
1901
    d_m3TracePrepare
1902
1903
179M
    IM3Function function = immediate(IM3Function);
1904
#if d_m3EntryKeepsFrame
1905
    IM3Memory memory = m3MemInfo(_mem);
1906
#endif
1907
1908
179M
    if (EntryFits(function, _sp, _mem)) {
1909
179M
        EnterFrame(function, _sp);
1910
1911
179M
#if !d_m3EntryKeepsFrame
1912
        // there's nothing left to do once the body returns, so hand this native frame
1913
        // over to it. That's what lets op_ReturnCall tail-call in constant native stack.
1914
179M
        nextOpDirect();
1915
#else
1916
1917
#  if d_m3EnableStrace >= 2
1918
        d_m3TracePrint("%s %s {", m3_GetFunctionName(function), SPrintFunctionArgList(function, _sp + function->numRetSlots));
1919
        trace_rt->callDepth++;
1920
#  endif
1921
1922
        m3ret_t r = nextOpImpl();
1923
1924
#  if d_m3EnableStrace >= 2
1925
        trace_rt->callDepth--;
1926
1927
        if (r) {
1928
            d_m3TracePrint("} !trap = %s", (char*)r);
1929
        } else if (GetFunctionNumReturns(function)) {
1930
            d_m3TracePrint("} = %s", SPrintFunctionRetList(function->funcType, _sp));
1931
        } else {
1932
            d_m3TracePrint("}");
1933
        }
1934
#  endif
1935
1936
        if (M3_UNLIKELY(r)) {
1937
            _mem = memory->mallocated;
1938
#  if d_m3HasStackSwitching
1939
            if (M3_UNLIKELY(r == m3Err_continuationSuspended)) {
1940
                return RecordEntryFrame(m3MemRuntime(_mem), _pc, _sp, memory, function);
1941
            }
1942
#  endif
1943
            fillBacktraceFrame();
1944
        }
1945
        forwardTrap(r);
1946
#endif // d_m3EntryKeepsFrame
1947
179M
    } else {
1948
6.35k
        newTrap(m3Err_trapStackOverflow);
1949
6.35k
    }
1950
179M
}
1951
1952
1953
d_m3Op(Loop)
1954
6.26M
{
1955
6.26M
    d_m3CheckNativeStack();
1956
1957
    d_m3TracePrepare
1958
1959
    // regs are unused coming into a loop anyway
1960
    // this reduces code size & stack usage
1961
6.26M
    d_m3ClearRegisters
1962
1963
6.26M
    m3ret_t   r;
1964
1965
6.26M
    IM3Memory memory = m3MemInfo(_mem);
1966
1967
10.9M
    do {
1968
#if d_m3EnableStrace >= 3
1969
        d_m3TracePrint("iter {");
1970
        trace_rt->callDepth++;
1971
#endif
1972
10.9M
        r = nextOpImpl();
1973
1974
#if d_m3EnableStrace >= 3
1975
        trace_rt->callDepth--;
1976
        d_m3TracePrint("}");
1977
#endif
1978
        // linear memory pointer needs refreshed here because the block it's looping over
1979
        // can potentially invoke the grow operation.
1980
10.9M
        _mem = memory->mallocated;
1981
10.9M
    } while (r == _pc);
1982
1983
6.26M
#if d_m3HasStackSwitching
1984
    // The loop's identity is its own pc, which is also where its body starts,
1985
    // so replaying it needs nothing else. Without this the continue sentinel
1986
    // has no frame left to land in after a resume and gets mistaken for a trap.
1987
6.26M
    if (M3_UNLIKELY(r == m3Err_continuationSuspended)) {
1988
0
        return RecordLoopFrame(m3MemRuntime(_mem), _pc, _sp, memory);
1989
0
    }
1990
6.26M
#endif
1991
1992
6.26M
    forwardTrap(r);
1993
6.26M
}
1994
1995
1996
#if d_m3HasExceptionHandling
1997
1998
// try_table. Like op_Loop this claims a native frame, and for the same reason:
1999
// a throw unwinds by returning m3Err_pendingException up the native stack, so
2000
// something has to be standing there to catch it.
2001
//
2002
// Immediates: the clause count, then two words per clause - the tag to match
2003
// (NULL for catch_all / catch_all_ref) and the PC of the stub that moves the
2004
// payload into place and branches to the clause's label. The body follows.
2005
//
2006
// The frame stays alive after the body falls through or branches out of the try
2007
// region, but the handler record is popped at those points (op_PopHandlers), so
2008
// a later throw sees this frame is no longer the innermost one and passes it by.
2009
//
2010
// The handler stack is just a depth counter: an unwind stops at whichever frame
2011
// finds the count still standing at the value its own push produced, which is
2012
// the innermost try region that hasn't been popped.
2013
d_m3Op(TryTable)
2014
2.46M
{
2015
2.46M
    d_m3CheckNativeStack();
2016
2017
2.46M
    IM3Memory  memory = m3MemInfo(_mem);
2018
2.46M
    IM3Runtime runtime = m3MemRuntime(_mem);
2019
2020
2.46M
    u32        numClauses = immediate(u32);
2021
2022
2.46M
    pc_t       clauses = _pc;
2023
2.46M
    pc_t       body = _pc + 2 * numClauses;
2024
2025
2.46M
    u32        depth = ++runtime->tryDepth;
2026
2027
2.46M
    m3ret_t    r = jumpOpImpl(body);
2028
2029
    // the body can have grown linear memory out from under us
2030
2.46M
    _mem = memory->mallocated;
2031
2032
    // control is leaving this frame for good, so this try is done either way
2033
2.46M
    bool isInnermost = (runtime->tryDepth == depth);
2034
2.46M
    runtime->tryDepth = depth - 1;
2035
2036
2.46M
#  if d_m3HasStackSwitching
2037
2.46M
    if (M3_UNLIKELY(r == m3Err_continuationSuspended)) {
2038
0
        return RecordTryFrame(runtime, clauses, _sp, memory, numClauses, isInnermost);
2039
0
    }
2040
2.46M
#  endif
2041
2042
2.46M
    if (M3_UNLIKELY(r == m3Err_pendingException) and isInnermost) {
2043
1.05M
        const M3Exception* exception = runtime->pendingException;
2044
2045
1.05M
        for (u32 i = 0; i < numClauses; ++i) {
2046
853k
            IM3Tag tag = (IM3Tag)clauses[2 * i];
2047
2048
853k
            if (tag == NULL or tag == exception->tag) {
2049
853k
                pc_t handler = (pc_t)clauses[2 * i + 1];
2050
2051
                // an unwind leaves nothing meaningful in the registers
2052
853k
                d_m3ClearRegisters
2053
2054
853k
                jumpOpDirect(handler);
2055
853k
            }
2056
853k
        }
2057
2058
        // no clause matched: the exception carries on up
2059
1.05M
    }
2060
2061
2.46M
    forwardTrap(r);
2062
2.46M
}
2063
2064
2065
// Head of a catch clause's stub: copies the caught exception's payload into the
2066
// slots the stub's branch expects, and the exnref itself for a _ref clause.
2067
//
2068
// A clause that takes no exnref is the end of the road for this exception, so
2069
// it is released here rather than waiting for the call to finish - a module
2070
// that throws inside a loop would otherwise pile up one object per lap. Not so
2071
// once an exnref has been handed out: a local, a global or a table may still be
2072
// holding it, ready for throw_ref.
2073
d_m3Op(CatchPayload)
2074
853k
{
2075
853k
    IM3Runtime   runtime = m3MemRuntime(_mem);
2076
853k
    M3Exception* exception = runtime->pendingException;
2077
2078
853k
    u32          numArgs = immediate(u32);
2079
2080
853k
    for (u32 i = 0; i < numArgs; ++i) {
2081
0
        i32 offset = immediate(i32);
2082
0
        u32 is64 = immediate(u32);
2083
0
        u64 value = exception->args[i];
2084
2085
0
        if (is64) {
2086
0
            *(u64*)(_sp + offset) = value;
2087
0
        } else {
2088
0
            *(u32*)(_sp + offset) = (u32)value;
2089
0
        }
2090
0
    }
2091
2092
853k
    i32 refOffset = immediate(i32);
2093
2094
853k
    if (refOffset >= 0) {
2095
0
        *(M3Exception**)(_sp + refOffset) = exception;
2096
0
        exception->reified = true;
2097
853k
    } else if (not exception->reified) {
2098
853k
        FreeException(runtime, exception);
2099
853k
    }
2100
2101
853k
    nextOp();
2102
853k
}
2103
2104
2105
d_m3Op(Throw)
2106
853k
{
2107
853k
    IM3Runtime   runtime = m3MemRuntime(_mem);
2108
2109
853k
    IM3Tag       tag = immediate(IM3Tag);
2110
853k
    u32          numArgs = immediate(u32);
2111
2112
853k
    M3Exception* exception = NewException(runtime, tag, numArgs);
2113
2114
853k
    if (M3_UNLIKELY(not exception)) {
2115
0
        newTrap(m3Err_mallocFailed);
2116
0
    }
2117
2118
853k
    for (u32 i = 0; i < numArgs; ++i) {
2119
1
        i32 offset = immediate(i32);
2120
1
        u32 is64 = immediate(u32);
2121
2122
1
        exception->args[i] = is64 ? *(u64*)(_sp + offset) : *(u32*)(_sp + offset);
2123
1
    }
2124
2125
853k
    runtime->pendingException = exception;
2126
2127
853k
    return m3Err_pendingException;
2128
853k
}
2129
2130
2131
d_m3Op(ThrowRef)
2132
13
{
2133
13
    M3Exception* exception = slot(M3Exception*);
2134
2135
13
    if (M3_UNLIKELY(not exception)) {
2136
13
        newTrap(m3Err_trapNullReference);
2137
13
    }
2138
2139
0
    m3MemRuntime(_mem)->pendingException = exception;
2140
2141
0
    return m3Err_pendingException;
2142
13
}
2143
2144
2145
// Emitted where control leaves a try region without leaving op_TryTable's native
2146
// frame: falling out of the block's end, or branching past it. The count is how
2147
// many try regions the exit crosses.
2148
d_m3Op(PopHandlers)
2149
1.37M
{
2150
1.37M
    IM3Runtime runtime = m3MemRuntime(_mem);
2151
2152
1.37M
    u32        count = immediate(u32);
2153
2154
1.37M
    runtime->tryDepth -= count;
2155
2156
1.37M
    nextOp();
2157
1.37M
}
2158
2159
#endif // d_m3HasExceptionHandling
2160
2161
#if d_m3HasStackSwitching
2162
2163
d_m3Op(ContNew)
2164
0
{
2165
0
    IM3Runtime  runtime = m3MemRuntime(_mem);
2166
0
    IM3FuncType funcType = immediate(IM3FuncType);
2167
0
    i32         dstSlot = immediate(i32);
2168
0
    i32         funcSlot = immediate(i32);
2169
2170
0
    IM3Function func = *(IM3Function*)(_sp + funcSlot);
2171
0
    if (M3_UNLIKELY(not func)) {
2172
0
        newTrap(m3Err_trapNullFunctionRef);
2173
0
    }
2174
2175
    // refused before a record exists, so a trap here leaves nothing behind
2176
0
    if (M3_UNLIKELY(not Continuation_CanAcquireStack(runtime))) {
2177
0
        newTrap(m3Err_continuationLimitExceeded);
2178
0
    }
2179
0
    IM3Continuation cont = Continuation_New(runtime, funcType, func);
2180
0
    if (M3_UNLIKELY(not cont)) {
2181
0
        newTrap(m3Err_mallocFailed);
2182
0
    }
2183
2184
0
    M3Result allocation = Continuation_AcquireStack(runtime, cont);
2185
0
    if (M3_UNLIKELY(allocation)) {
2186
0
        cont->state = cont_consumed;
2187
0
        newTrap(allocation);
2188
0
    }
2189
0
    *(IM3Continuation*)(_sp + dstSlot) = cont;
2190
0
    nextOp();
2191
0
}
2192
2193
2194
static
2195
IM3Continuation InnermostSuspended (IM3Continuation i_cont);
2196
2197
d_m3Op(ContBind)
2198
0
{
2199
0
    IM3Runtime      runtime = m3MemRuntime(_mem);
2200
0
    IM3FuncType     ct1 = immediate(IM3FuncType);
2201
0
    IM3FuncType     ct2 = immediate(IM3FuncType);
2202
0
    i32             dstSlot = immediate(i32);
2203
0
    i32             contSlot = immediate(i32);
2204
0
    u32             numBound = immediate(u32);
2205
2206
0
    IM3Continuation srcCont = *(IM3Continuation*)(_sp + contSlot);
2207
0
    if (M3_UNLIKELY(not srcCont)) {
2208
0
        newTrap(m3Err_trapNullContinuationRef);
2209
0
    }
2210
0
    if (M3_UNLIKELY(srcCont->state == cont_consumed || srcCont->state == cont_running)) {
2211
0
        newTrap(m3Err_trapContinuationConsumed);
2212
0
    }
2213
2214
0
    IM3Continuation dstCont = Continuation_New(runtime, ct2, srcCont->entryFunction);
2215
0
    if (M3_UNLIKELY(not dstCont)) {
2216
0
        newTrap(m3Err_mallocFailed);
2217
0
    }
2218
2219
    // the bound continuation takes over the original's execution state whole,
2220
    // recorded native frames included: binding a suspended continuation must
2221
    // not cost it the frames it has to be resumed through
2222
0
    dstCont->entryFunction = srcCont->entryFunction;
2223
0
    dstCont->valStack = srcCont->valStack;
2224
0
    dstCont->numStackSlots = srcCont->numStackSlots;
2225
0
    dstCont->frames = srcCont->frames;
2226
0
    dstCont->framesCap = srcCont->framesCap;
2227
0
    dstCont->numFrames = srcCont->numFrames;
2228
0
    dstCont->sp = srcCont->sp;
2229
0
    dstCont->pc = srcCont->pc;
2230
0
    dstCont->suspendPoint = srcCont->suspendPoint;
2231
0
    dstCont->r0 = srcCont->r0;
2232
0
#  if d_m3HasFloat
2233
0
    dstCont->fp0 = srcCont->fp0;
2234
0
#  endif
2235
0
    dstCont->boundArgsCount = srcCont->boundArgsCount;
2236
0
    dstCont->state = srcCont->state;
2237
0
#  if d_m3HasExceptionHandling
2238
0
    dstCont->resumeThrow = srcCont->resumeThrow;
2239
0
    srcCont->resumeThrow = NULL;
2240
0
#  endif
2241
2242
0
    dstCont->numSuspendResults = srcCont->numSuspendResults;
2243
0
    for (u32 j = 0; j < srcCont->numSuspendResults; ++j) {
2244
0
        dstCont->suspendResultOffsets[j] = srcCont->suspendResultOffsets[j];
2245
0
        dstCont->suspendResultIs64[j] = srcCont->suspendResultIs64[j];
2246
0
    }
2247
2248
0
    if (dstCont->state == cont_allocated) {
2249
0
        u16 numRets = ct1->contFuncType ? GetFuncTypeNumResults(ct1->contFuncType) : 0;
2250
0
        for (u32 i = 0; i < numBound; ++i) {
2251
0
            i32 argSlot = immediate(i32);
2252
0
            u32 is64 = immediate(u32);
2253
0
            u32 targetIdx = (numRets + dstCont->boundArgsCount) * c_ioSlotCount;
2254
0
            if (is64) {
2255
0
                *(u64*)(dstCont->valStack + targetIdx) = *(u64*)(_sp + argSlot);
2256
0
            } else {
2257
0
                *(u32*)(dstCont->valStack + targetIdx) = *(u32*)(_sp + argSlot);
2258
0
            }
2259
0
            dstCont->boundArgsCount++;
2260
0
        }
2261
0
    } else {
2262
0
        IM3Continuation inner = InnermostSuspended(dstCont);
2263
0
        for (u32 i = 0; i < numBound; ++i) {
2264
0
            i32 argSlot = immediate(i32);
2265
0
            u32 is64 = immediate(u32);
2266
0
            u32 dstIdx = dstCont->boundArgsCount;
2267
0
            if (dstIdx < inner->numSuspendResults) {
2268
0
                i32 dstOffset = inner->suspendResultOffsets[dstIdx];
2269
0
                if (is64) {
2270
0
                    *(u64*)(inner->sp + dstOffset) = *(u64*)(_sp + argSlot);
2271
0
                } else {
2272
0
                    *(u32*)(inner->sp + dstOffset) = *(u32*)(_sp + argSlot);
2273
0
                }
2274
0
            }
2275
0
            dstCont->boundArgsCount++;
2276
0
        }
2277
0
    }
2278
2279
0
    srcCont->valStack = NULL;
2280
0
    srcCont->frames = NULL;
2281
0
    srcCont->framesCap = 0;
2282
0
    srcCont->numFrames = 0;
2283
0
    srcCont->state = cont_consumed;
2284
2285
0
    *(IM3Continuation*)(_sp + dstSlot) = dstCont;
2286
0
    nextOp();
2287
0
}
2288
2289
2290
// Finds the resume whose handler answers this tag, walking out through the
2291
// continuations that resumed us. i_kind picks which sort of handler counts -
2292
// 0 for (on $e $l), 1 for (on $e switch). The spec is explicit that the search
2293
// walks past a handler of the wrong sort even when the tag matches, so the
2294
// kind is part of the match rather than something checked afterwards.
2295
static
2296
IM3Continuation FindHandler (IM3Continuation i_cont, IM3Tag i_tag, u8 i_kind, pc_t* o_stubPC)
2297
0
{
2298
0
    IM3Tag queryTag = (i_tag and i_tag->resolved) ? i_tag->resolved : i_tag;
2299
2300
0
    for (IM3Continuation cont = i_cont; cont; cont = cont->parent) {
2301
0
        for (u32 h = 0; h < cont->numHandlers; ++h) {
2302
0
            pc_t   entry = cont->handlersPC + (h * 3);
2303
0
            IM3Tag handlerTag = (IM3Tag)(*(entry + 1));
2304
0
            if (handlerTag and handlerTag->resolved) {
2305
0
                handlerTag = handlerTag->resolved;
2306
0
            }
2307
2308
0
            if ((u32)(uintptr_t)(*entry) == i_kind and handlerTag == queryTag) {
2309
0
                if (o_stubPC) {
2310
0
                    *o_stubPC = (pc_t)(*(entry + 2));
2311
0
                }
2312
0
                return cont;
2313
0
            }
2314
0
        }
2315
0
    }
2316
2317
0
    return NULL;
2318
0
}
2319
2320
2321
// Nulls the slots a suspend or switch leaves waiting for whatever resumes it.
2322
// Until something writes them they are part of the suspended frame holding
2323
// nothing, and a snapshot taken meanwhile reads each one as the type it will
2324
// have: a reference there has to be null rather than whatever the slot held.
2325
static
2326
void ClearSuspendResults (IM3Continuation io_cont, m3stack_t i_sp)
2327
0
{
2328
0
    for (u32 i = 0; i < io_cont->numSuspendResults; ++i) {
2329
0
        if (io_cont->suspendResultIs64[i]) {
2330
0
            *(u64*)(i_sp + io_cont->suspendResultOffsets[i]) = 0;
2331
0
        } else {
2332
0
            *(m3slot_t*)(i_sp + io_cont->suspendResultOffsets[i]) = 0;
2333
0
        }
2334
0
    }
2335
0
}
2336
2337
2338
d_m3Op(Suspend)
2339
6
{
2340
6
    IM3Runtime      runtime = m3MemRuntime(_mem);
2341
6
    IM3Continuation cont = runtime->activeContinuation;
2342
6
    if (M3_UNLIKELY(not cont)) {
2343
6
        newTrap(m3Err_trapUnhandledControlTag);
2344
6
    }
2345
2346
0
    IM3Tag tag = immediate(IM3Tag);
2347
0
    u32    numParams = immediate(u32);
2348
2349
0
    runtime->numSuspendPayload = numParams;
2350
0
    for (u32 i = 0; i < numParams; ++i) {
2351
0
        i32 paramSlot = immediate(i32);
2352
0
        u32 is64 = immediate(u32);
2353
0
        if (is64) {
2354
0
            runtime->suspendPayload[i] = *(u64*)(_sp + paramSlot);
2355
0
        } else {
2356
0
            runtime->suspendPayload[i] = (u64) * (u32*)(_sp + paramSlot);
2357
0
        }
2358
0
        runtime->suspendPayloadIs64[i] = is64;
2359
0
    }
2360
2361
0
    u32 numResults = immediate(u32);
2362
0
    cont->numSuspendResults = numResults;
2363
0
    for (u32 i = 0; i < numResults; ++i) {
2364
0
        cont->suspendResultOffsets[i] = immediate(i32);
2365
0
        cont->suspendResultIs64[i] = immediate(u32);
2366
0
    }
2367
2368
0
    ClearSuspendResults(cont, _sp);
2369
2370
0
    pc_t            matchedStubPC = NULL;
2371
0
    IM3Continuation searchCont = FindHandler(cont, tag, 0, &matchedStubPC);
2372
2373
0
    if (M3_UNLIKELY(not searchCont)) {
2374
0
        newTrap(m3Err_trapUnhandledControlTag);
2375
0
    }
2376
2377
0
    runtime->suspendStubPC = matchedStubPC;
2378
0
    runtime->suspendHandlerCont = searchCont;
2379
0
    runtime->switchTarget = NULL;
2380
0
    runtime->suspendTag = tag;
2381
2382
0
    cont->pc = _pc;
2383
0
    cont->suspendPoint = safepoint_suspend;
2384
0
    cont->sp = _sp;
2385
0
    cont->r0 = _r0;
2386
0
#  if d_m3HasFloat
2387
0
    cont->fp0 = _fp0;
2388
0
#  endif
2389
0
    cont->boundArgsCount = 0;
2390
2391
0
    return m3Err_continuationSuspended;
2392
0
}
2393
2394
2395
// ReplayFrames and RunUnderHandlers call each other: a captured resume is a
2396
// frame like any other, and what it stands back up is a continuation with
2397
// frames of its own.
2398
static
2399
m3ret_t RunUnderHandlers (IM3Runtime i_runtime, IM3Continuation* io_cont,
2400
                          pc_t i_handlersPC, u32 i_numHandlers, M3MemoryHeader** io_mem);
2401
static
2402
void TakeContinuationResults (IM3Continuation i_cont, m3stack_t i_sp,
2403
                              pc_t i_resultsPC, u32 i_numResults);
2404
static
2405
m3ret_t ResumePastCheck (IM3Continuation i_cont, M3MemoryHeader* _mem);
2406
2407
// Whether the suspension point a replay has come down to is resumed past its
2408
// check. Only the first one reached answers to m3_ResumeRuntime's request: that
2409
// is the one the runtime paused at, and whatever it is, the request is spent.
2410
static inline
2411
bool ResumesPastCheck (IM3Runtime io_runtime, IM3Continuation i_cont)
2412
0
{
2413
0
    bool pass = io_runtime->resumePastCheck;
2414
2415
0
    io_runtime->resumePastCheck = false;
2416
2417
0
    return pass and (i_cont->suspendPoint == safepoint_op or i_cont->suspendPoint == safepoint_entry);
2418
0
}
2419
2420
2421
// Rebuilds the native frames the suspend unwound through and lands on the
2422
// suspension point at the bottom of them.
2423
//
2424
// Frames were recorded innermost first, which is the order the unwind met
2425
// them, so this walks down from the outermost and recurses toward the
2426
// suspension point: by the time anything runs again, the native stack looks
2427
// the way it did when the suspend left.
2428
//
2429
// Each case has to stand in for one operation completely - claim the frame it
2430
// claimed, and answer the return value the way it would - including recording
2431
// itself again, because the continuation is free to suspend a second time from
2432
// inside the chain being rebuilt here. That second suspend refills frames[]
2433
// from index 0 while this walk is still in it, which is why every level takes
2434
// its own copy of the frame on the way down, before anything can run.
2435
static
2436
m3ret_t ReplayFrames (IM3Continuation i_cont, i32 i_depth, M3MemoryHeader* _mem)
2437
0
{
2438
0
    IM3Runtime runtime = m3MemRuntime(_mem);
2439
0
    m3ret_t    r = m3Err_none;
2440
2441
0
#  if d_m3MaxNativeStack > 0
2442
0
    {
2443
0
        void* limit = runtime->stackLimit;
2444
2445
0
        if (M3_UNLIKELY(limit and m3_NativeStackPtr() < limit)) {
2446
0
            return m3Err_trapStackOverflow;
2447
0
        }
2448
0
    }
2449
0
#  endif
2450
2451
0
    if (i_depth < 0) {
2452
0
        bool pastCheck = ResumesPastCheck(runtime, i_cont);
2453
2454
0
#  if d_m3HasExceptionHandling
2455
        // resume_throw stops here: rather than carrying on from the suspension
2456
        // point, the exception is raised at it and travels back out through the
2457
        // try regions this walk has just rebuilt above
2458
0
        if (M3_UNLIKELY(i_cont->resumeThrow)) {
2459
0
            runtime->pendingException = i_cont->resumeThrow;
2460
0
            i_cont->resumeThrow = NULL;
2461
2462
0
            return m3Err_pendingException;
2463
0
        }
2464
0
#  endif
2465
0
        if (pastCheck) {
2466
0
            return ResumePastCheck(i_cont, _mem);
2467
0
        }
2468
2469
0
        return d_m3CallWithRegs(i_cont->pc, i_cont->sp, _mem, i_cont->r0, i_cont->fp0);
2470
0
    }
2471
2472
0
    M3Frame frame = i_cont->frames[i_depth];
2473
2474
    // frame_try brackets the recursion with its own bookkeeping, and
2475
    // frame_resume descends into another continuation entirely, so neither
2476
    // shares this one
2477
0
    bool    ownDescent = ((M3FrameKind)frame.kind == frame_resume);
2478
2479
0
#  if d_m3HasExceptionHandling
2480
0
    ownDescent = ownDescent or ((M3FrameKind)frame.kind == frame_try);
2481
0
#  endif
2482
2483
0
    if (not ownDescent) {
2484
0
        r = ReplayFrames(i_cont, i_depth - 1, _mem);
2485
0
        _mem = frame.memory->mallocated;
2486
0
    }
2487
2488
0
    switch ((M3FrameKind)frame.kind) {
2489
0
    case frame_call:
2490
0
        if (M3_LIKELY(not r)) {
2491
            // the callee returned: carry on in the caller, with the registers
2492
            // op_Call's own frame had been holding across the call
2493
0
            return d_m3CallWithRegs(frame.pc, frame.sp, _mem, frame.call.r0, frame.call.fp0);
2494
0
        }
2495
2496
0
        if (M3_UNLIKELY(r == m3Err_continuationSuspended)) {
2497
0
            return Continuation_RecordFrame(runtime, &frame);
2498
0
        }
2499
#  if d_m3RecordBacktraces
2500
        PushBacktraceFrame(runtime, frame.pc - 1);
2501
#  endif
2502
0
        return r;
2503
2504
0
    case frame_loop: {
2505
0
        m3stack_t _sp = frame.sp;
2506
0
        m3reg_t   _r0 = 0;
2507
0
#  if d_m3HasFloat
2508
0
        f64 _fp0 = 0.;
2509
0
#  endif
2510
        // op_Loop's protocol: the body hands its own pc back to ask for
2511
        // another lap. Dispatched the way op_Loop dispatches it, so a yield
2512
        // hook sees the same back edges it always did.
2513
0
        while (r == (m3ret_t)frame.pc) {
2514
0
            r = jumpOpImpl(frame.pc);
2515
0
            _mem = frame.memory->mallocated;
2516
0
        }
2517
2518
0
        if (M3_UNLIKELY(r == m3Err_continuationSuspended)) {
2519
0
            return Continuation_RecordFrame(runtime, &frame);
2520
0
        }
2521
0
        return r;
2522
0
    }
2523
2524
0
#  if d_m3HasExceptionHandling
2525
0
    case frame_try: {
2526
0
        m3stack_t _sp = frame.sp;
2527
0
        m3reg_t   _r0 = 0;
2528
0
#    if d_m3HasFloat
2529
0
        f64 _fp0 = 0.;
2530
0
#    endif
2531
0
        (void)_sp;
2532
0
        (void)_r0;
2533
0
#    if d_m3HasFloat
2534
0
        (void)_fp0;
2535
0
#    endif
2536
2537
        // this try region is standing again, so it counts towards the depth
2538
        // once more - unless op_PopHandlers had already retired it before the
2539
        // suspend, in which case it is only here to be walked past
2540
0
        u32 depth = ++runtime->tryDepth;
2541
2542
0
        if (not frame.try_.handlersLive) {
2543
0
            runtime->tryDepth = depth - 1;
2544
0
        }
2545
2546
0
        r = ReplayFrames(i_cont, i_depth - 1, _mem);
2547
0
        _mem = frame.memory->mallocated;
2548
2549
0
        bool isInnermost = (runtime->tryDepth == depth);
2550
0
        runtime->tryDepth = depth - 1;
2551
2552
0
        if (M3_UNLIKELY(r == m3Err_continuationSuspended)) {
2553
0
            frame.try_.handlersLive = isInnermost;
2554
0
            return Continuation_RecordFrame(runtime, &frame);
2555
0
        }
2556
2557
0
        if (M3_UNLIKELY(r == m3Err_pendingException) and isInnermost) {
2558
0
            const M3Exception* exception = runtime->pendingException;
2559
2560
0
            for (u32 i = 0; i < frame.try_.numClauses; ++i) {
2561
0
                IM3Tag tag = (IM3Tag)frame.pc[2 * i];
2562
2563
0
                if (tag == NULL or tag == exception->tag) {
2564
0
                    pc_t handler = (pc_t)frame.pc[2 * i + 1];
2565
2566
0
                    d_m3ClearRegisters
2567
2568
                    // op_TryTable hands its frame to the handler, but this is
2569
                    // not an operation and cannot: the replay stands in for
2570
                    // that frame, so it keeps it and passes the answer on.
2571
0
                    return jumpOpImpl(handler);
2572
0
                }
2573
0
            }
2574
0
        }
2575
0
        return r;
2576
0
    }
2577
0
#  endif
2578
2579
0
    case frame_resume: {
2580
        // A resume that the suspend passed straight through. Standing it up
2581
        // again means running the continuation it had under it, under the same
2582
        // handlers - and that continuation carries the suspension point, so it
2583
        // is where the rest of the replay happens.
2584
0
        IM3Continuation inner = frame.resume.cont;
2585
2586
0
        r = RunUnderHandlers(runtime, &inner, frame.resume.handlersPC,
2587
0
                             frame.resume.numHandlers, &_mem);
2588
2589
0
        if (r == m3Err_none) {
2590
0
            inner->state = cont_consumed;
2591
2592
0
            TakeContinuationResults(inner, frame.sp, frame.resume.resultsPC,
2593
0
                                    frame.resume.numResults);
2594
0
            Continuation_RecycleStack(runtime, inner);
2595
2596
0
            return d_m3CallWithRegs(frame.pc, frame.sp, _mem, 0, 0.);
2597
0
        }
2598
2599
0
        if (M3_UNLIKELY(r == m3Err_continuationSuspended)) {
2600
0
            if (runtime->suspendHandlerCont != inner) {
2601
0
                frame.resume.cont = inner;
2602
0
                return Continuation_RecordFrame(runtime, &frame);
2603
0
            }
2604
2605
0
            IM3Continuation suspended = Continuation_ForkSuspended(runtime, inner);
2606
0
            if (M3_UNLIKELY(not suspended)) {
2607
0
                return m3Err_mallocFailed;
2608
0
            }
2609
0
            runtime->suspendedContinuation = suspended;
2610
0
            if (runtime->suspendStubPC) {
2611
0
                return d_m3CallWithRegs(runtime->suspendStubPC, frame.sp, _mem, 0, 0.);
2612
0
            } else {
2613
0
                return m3Err_trapUnhandledControlTag;
2614
0
            }
2615
0
        } else {
2616
0
            inner->state = cont_consumed;
2617
0
            Continuation_RecycleStack(runtime, inner);
2618
0
        }
2619
2620
0
        return r;
2621
0
    }
2622
2623
#  if d_m3EntryKeepsFrame
2624
    case frame_entry:
2625
        if (M3_UNLIKELY(r)) {
2626
            if (M3_UNLIKELY(r == m3Err_continuationSuspended)) {
2627
                return Continuation_RecordFrame(runtime, &frame);
2628
            }
2629
#    if d_m3RecordBacktraces
2630
            FillBacktraceFunctionInfo(runtime, frame.entry.function);
2631
#    else
2632
            (void)frame.entry.function;
2633
#    endif
2634
        }
2635
        return r;
2636
#  endif
2637
0
    }
2638
2639
0
    return r;
2640
0
}
2641
2642
2643
// Where a continuation's i-th incoming value goes. A continuation that has not
2644
// started yet takes them as the arguments of its entry frame, laid out above
2645
// its return slots; one that is suspended takes them in the slots its own
2646
// suspend or switch left waiting.
2647
static
2648
void* ContinuationArgDest (IM3Continuation i_cont, u32 i_index)
2649
0
{
2650
0
    if (i_cont->state == cont_allocated) {
2651
0
        IM3FuncType inner = i_cont->type ? i_cont->type->contFuncType : NULL;
2652
0
        u16         numRets = inner ? GetFuncTypeNumResults(inner) : 0;
2653
2654
0
        return i_cont->valStack + (numRets + i_index) * c_ioSlotCount;
2655
0
    }
2656
2657
0
    if (i_index < i_cont->numSuspendResults) {
2658
0
        return i_cont->sp + i_cont->suspendResultOffsets[i_index];
2659
0
    }
2660
2661
0
    return NULL;
2662
0
}
2663
2664
2665
// Hands a switch's payload to the peer, and after it the continuation that
2666
// switched away - the reference that lets the peer come back this way.
2667
static
2668
void HandOverToPeer (IM3Runtime i_runtime, IM3Continuation io_peer, IM3Continuation i_from)
2669
0
{
2670
0
    u32 numArgs = i_runtime->numSuspendPayload;
2671
0
    u32 base = (io_peer->state == cont_allocated) ? io_peer->boundArgsCount : 0;
2672
2673
0
    for (u32 i = 0; i < numArgs; ++i) {
2674
0
        void* dest = ContinuationArgDest(io_peer, base + i);
2675
2676
0
        if (dest) {
2677
0
            if (i_runtime->suspendPayloadIs64[i]) {
2678
0
                *(u64*)dest = i_runtime->suspendPayload[i];
2679
0
            } else {
2680
0
                *(u32*)dest = (u32)i_runtime->suspendPayload[i];
2681
0
            }
2682
0
        }
2683
0
    }
2684
2685
0
    void* refDest = ContinuationArgDest(io_peer, base + numArgs);
2686
2687
0
    if (refDest) {
2688
0
        *(IM3Continuation*)refDest = i_from;
2689
0
    }
2690
2691
0
    if (io_peer->state == cont_allocated) {
2692
0
        io_peer->boundArgsCount += numArgs + 1;
2693
0
    }
2694
0
}
2695
2696
2697
// resume, resume_throw and resume_throw_ref. The three differ only in what the
2698
// continuation is handed to start with, which is what the mode immediate says,
2699
// so everything after that - the handler table, the switch loop, the results -
2700
// is written once.
2701
// The innermost continuation of a capture: the one whose suspension point is
2702
// at the bottom of it, and so the one whose waiting slots any values handed to
2703
// the capture belong in. A resume the suspend travelled through leaves its
2704
// record at the foot of the frame list, which is the link to follow.
2705
static
2706
IM3Continuation InnermostSuspended (IM3Continuation i_cont)
2707
0
{
2708
0
    while (i_cont->numFrames and (M3FrameKind) i_cont->frames[0].kind == frame_resume) {
2709
0
        i_cont = i_cont->frames[0].resume.cont;
2710
0
    }
2711
2712
0
    return i_cont;
2713
0
}
2714
2715
2716
// Runs a continuation under one handler table until something comes back that
2717
// is not a switch, and reports which continuation was running when it did: a
2718
// switch under this table takes the place of the one that switched away, and
2719
// whatever is running is what the handler table belongs to.
2720
static
2721
m3ret_t RunUnderHandlers (IM3Runtime i_runtime, IM3Continuation* io_cont,
2722
                          pc_t i_handlersPC, u32 i_numHandlers, M3MemoryHeader** io_mem)
2723
0
{
2724
0
    IM3Continuation cont = *io_cont;
2725
0
    IM3Continuation parent = i_runtime->activeContinuation;
2726
0
    IM3Memory       memory = m3MemInfo(*io_mem);
2727
0
    m3ret_t         r;
2728
2729
0
    for (;;) {
2730
0
#  if d_m3HasExceptionHandling
2731
        // aborting a continuation that never started: there is no suspension
2732
        // point to raise at, so the exception simply comes straight back out
2733
0
        if (M3_UNLIKELY(cont->resumeThrow and cont->numFrames == 0)) {
2734
0
            i_runtime->pendingException = cont->resumeThrow;
2735
0
            cont->resumeThrow = NULL;
2736
0
            cont->state = cont_consumed;
2737
0
            r = m3Err_pendingException;
2738
0
            break;
2739
0
        }
2740
0
#  endif
2741
0
        bool isStarting = (cont->state == cont_allocated);
2742
2743
0
        if (isStarting) {
2744
0
            if (M3_UNLIKELY(not cont->entryFunction->compiled)) {
2745
0
                r = CompileFunction(cont->entryFunction);
2746
2747
0
                if (M3_UNLIKELY(r)) {
2748
0
                    break;
2749
0
                }
2750
0
            }
2751
0
            cont->pc = cont->entryFunction->compiled;
2752
0
            cont->sp = cont->valStack;
2753
0
            cont->numFrames = 0;
2754
0
        }
2755
2756
0
        cont->handlersPC = i_handlersPC;
2757
0
        cont->numHandlers = i_numHandlers;
2758
0
        cont->parent = parent;
2759
0
        cont->state = cont_running;
2760
0
        cont->boundArgsCount = 0;
2761
2762
0
        i_runtime->activeContinuation = cont;
2763
2764
0
        if (cont->numFrames) {
2765
            // a suspended continuation: put back the native frames it unwound
2766
            // through before landing on the suspension point. The count is
2767
            // cleared first because a second suspend records into the same
2768
            // array, starting over at index 0.
2769
0
            i32 outermost = (i32)cont->numFrames - 1;
2770
0
            cont->numFrames = 0;
2771
2772
0
            r = ReplayFrames(cont, outermost, *io_mem);
2773
0
        } else if (not isStarting and ResumesPastCheck(i_runtime, cont)) {
2774
0
            r = ResumePastCheck(cont, *io_mem);
2775
0
        } else {
2776
0
            r = d_m3CallWithRegs(cont->pc, cont->sp, *io_mem, 0, 0.);
2777
0
        }
2778
2779
0
        *io_mem = memory->mallocated;
2780
0
        i_runtime->activeContinuation = parent;
2781
2782
0
        if (r != m3Err_continuationSuspended) {
2783
0
            break;
2784
0
        }
2785
2786
0
        cont->state = cont_suspended;
2787
2788
        // not a switch, so it is a suspend and this is as far as we take it
2789
0
        if (not i_runtime->switchTarget or i_runtime->suspendHandlerCont != cont) {
2790
0
            break;
2791
0
        }
2792
2793
0
        IM3Continuation peer = i_runtime->switchTarget;
2794
0
        i_runtime->switchTarget = NULL;
2795
2796
0
        IM3Continuation suspended = Continuation_ForkSuspended(i_runtime, cont);
2797
0
        if (M3_UNLIKELY(not suspended)) {
2798
0
            r = m3Err_mallocFailed;
2799
0
            break;
2800
0
        }
2801
0
        IM3FuncType peerType = peer->type->contFuncType;
2802
0
        suspended->type = Module_ContTypeOfRef(peer->entryFunction->module,
2803
0
                                               GetFuncTypeParamType(peerType, (u16)(GetFuncTypeNumParams(peerType) - 1)));
2804
0
        HandOverToPeer(i_runtime, peer, suspended);
2805
2806
0
        cont = peer;
2807
0
    }
2808
2809
0
    *io_cont = cont;
2810
2811
0
    return r;
2812
0
}
2813
2814
2815
// Copies what a finished continuation left in its return slots into the slots
2816
// the resume site set aside for them.
2817
static
2818
void TakeContinuationResults (IM3Continuation i_cont, m3stack_t i_sp, pc_t i_resultsPC, u32 i_numResults)
2819
0
{
2820
0
    for (u32 i = 0; i < i_numResults; ++i) {
2821
0
        i32 resSlot = *(i32*)(i_resultsPC + 2 * i);
2822
0
        u32 is64 = *(u32*)(i_resultsPC + 2 * i + 1);
2823
0
        u32 srcIdx = i * c_ioSlotCount;
2824
2825
0
        if (is64) {
2826
0
            *(u64*)(i_sp + resSlot) = *(u64*)(i_cont->valStack + srcIdx);
2827
0
        } else {
2828
0
            *(u32*)(i_sp + resSlot) = *(u32*)(i_cont->valStack + srcIdx);
2829
0
        }
2830
0
    }
2831
0
}
2832
2833
2834
// resume, resume_throw and resume_throw_ref. The three differ only in what the
2835
// continuation is handed to start with, which is what the mode immediate says,
2836
// so everything after that - the handler table, the switch loop, the results -
2837
// is written once.
2838
d_m3Op(Resume)
2839
0
{
2840
0
    IM3Runtime      runtime = m3MemRuntime(_mem);
2841
0
    IM3FuncType     contFuncType = immediate(IM3FuncType);
2842
0
    i32             contSlot = immediate(i32);
2843
0
    u32             mode = immediate(u32);
2844
2845
0
    IM3Continuation cont = *(IM3Continuation*)(_sp + contSlot);
2846
0
    if (M3_UNLIKELY(not cont)) {
2847
0
        newTrap(m3Err_trapNullContinuationRef);
2848
0
    }
2849
0
    if (M3_UNLIKELY(cont->state == cont_consumed or cont->state == cont_running)) {
2850
0
        newTrap(m3Err_trapContinuationConsumed);
2851
0
    }
2852
2853
0
    IM3FuncType innerType = contFuncType->contFuncType ? contFuncType->contFuncType : contFuncType;
2854
0
    u16         numRets = GetFuncTypeNumResults(innerType);
2855
2856
0
    if (mode == d_m3ResumeThrowRef) {
2857
0
        i32 exnSlot = immediate(i32);
2858
2859
0
#  if d_m3HasExceptionHandling
2860
0
        M3Exception* exception = *(M3Exception**)(_sp + exnSlot);
2861
2862
0
        if (M3_UNLIKELY(not exception)) {
2863
0
            newTrap(m3Err_trapNullReference);
2864
0
        }
2865
2866
0
        InnermostSuspended(cont)->resumeThrow = exception;
2867
#  else
2868
        (void)exnSlot;
2869
        newTrap(m3Err_trapUnsupportedInstruction);
2870
#  endif
2871
0
    } else if (mode == d_m3ResumeThrow) {
2872
0
        IM3Tag exnTag = immediate(IM3Tag);
2873
0
        u32    numArgs = immediate(u32);
2874
2875
0
#  if d_m3HasExceptionHandling
2876
0
        M3Exception* exception = NewException(runtime, exnTag, numArgs);
2877
2878
0
        if (M3_UNLIKELY(not exception)) {
2879
0
            newTrap(m3Err_mallocFailed);
2880
0
        }
2881
2882
0
        for (u32 i = 0; i < numArgs; ++i) {
2883
0
            i32 offset = immediate(i32);
2884
0
            u32 is64 = immediate(u32);
2885
2886
0
            exception->args[i] = is64 ? *(u64*)(_sp + offset) : *(u32*)(_sp + offset);
2887
0
        }
2888
2889
0
        InnermostSuspended(cont)->resumeThrow = exception;
2890
#  else
2891
        (void)exnTag;
2892
        (void)numArgs;
2893
        newTrap(m3Err_trapUnsupportedInstruction);
2894
#  endif
2895
0
    } else {
2896
0
        u32 numArgs = immediate(u32);
2897
2898
0
        if (cont->state == cont_allocated) {
2899
0
            for (u32 i = 0; i < numArgs; ++i) {
2900
0
                i32 argSlot = immediate(i32);
2901
0
                u32 is64 = immediate(u32);
2902
0
                u32 targetIdx = (numRets + cont->boundArgsCount + i) * c_ioSlotCount;
2903
0
                if (is64) {
2904
0
                    *(u64*)(cont->valStack + targetIdx) = *(u64*)(_sp + argSlot);
2905
0
                } else {
2906
0
                    *(u32*)(cont->valStack + targetIdx) = *(u32*)(_sp + argSlot);
2907
0
                }
2908
0
            }
2909
0
            cont->boundArgsCount = 0;
2910
0
        } else {
2911
            // the waiting slots belong to whichever continuation holds the
2912
            // suspension point, which is not this one if a resume was captured
2913
            // along with it
2914
0
            IM3Continuation inner = InnermostSuspended(cont);
2915
2916
0
            for (u32 i = 0; i < numArgs; ++i) {
2917
0
                i32 argSlot = immediate(i32);
2918
0
                u32 is64 = immediate(u32);
2919
0
                u32 dstIdx = cont->boundArgsCount + i;
2920
0
                if (dstIdx < inner->numSuspendResults) {
2921
0
                    i32 dstOffset = inner->suspendResultOffsets[dstIdx];
2922
0
                    if (is64) {
2923
0
                        *(u64*)(inner->sp + dstOffset) = *(u64*)(_sp + argSlot);
2924
0
                    } else {
2925
0
                        *(u32*)(inner->sp + dstOffset) = *(u32*)(_sp + argSlot);
2926
0
                    }
2927
0
                }
2928
0
            }
2929
0
        }
2930
0
    }
2931
2932
0
    u32  numHandlers = immediate(u32);
2933
0
    pc_t handlersPC = _pc;
2934
0
    _pc += numHandlers * 3;
2935
2936
0
    u32       numResults = immediate(u32);
2937
0
    pc_t      resultsPC = _pc;
2938
2939
0
    IM3Memory memory = m3MemInfo(_mem);
2940
2941
0
    m3ret_t   r = RunUnderHandlers(runtime, &cont, handlersPC, numHandlers, &_mem);
2942
2943
0
    if (r == m3Err_none) {
2944
0
        cont->state = cont_consumed;
2945
2946
0
        TakeContinuationResults(cont, _sp, resultsPC, numResults);
2947
0
        Continuation_RecycleStack(runtime, cont);
2948
2949
0
        _pc += numResults * 2;
2950
0
        nextOp();
2951
0
    } else if (r == m3Err_continuationSuspended) {
2952
0
        if (M3_UNLIKELY(runtime->suspendHandlerCont != cont)) {
2953
0
            if (M3_UNLIKELY(not runtime->activeContinuation)) {
2954
0
                newTrap(m3Err_trapUnhandledControlTag);
2955
0
            }
2956
0
            M3Frame frame;
2957
0
            frame.kind = frame_resume;
2958
0
            frame.pc = resultsPC + numResults * 2;
2959
0
            frame.sp = _sp;
2960
0
            frame.memory = memory;
2961
0
            frame.resume.cont = cont;
2962
0
            frame.resume.handlersPC = handlersPC;
2963
0
            frame.resume.numHandlers = numHandlers;
2964
0
            frame.resume.resultsPC = resultsPC;
2965
0
            frame.resume.numResults = numResults;
2966
2967
0
            return Continuation_RecordFrame(runtime, &frame);
2968
0
        }
2969
2970
0
        IM3Continuation suspended = Continuation_ForkSuspended(runtime, cont);
2971
0
        if (M3_UNLIKELY(not suspended)) {
2972
0
            newTrap(m3Err_mallocFailed);
2973
0
        }
2974
0
        runtime->suspendedContinuation = suspended;
2975
2976
0
        if (runtime->suspendStubPC) {
2977
0
            jumpOpDirect(runtime->suspendStubPC);
2978
0
        } else {
2979
0
            newTrap(m3Err_trapUnhandledControlTag);
2980
0
        }
2981
0
    } else {
2982
0
        cont->state = cont_consumed;
2983
0
        Continuation_RecycleStack(runtime, cont);
2984
0
        pushBacktraceFrame();
2985
0
        forwardTrap(r);
2986
0
    }
2987
0
}
2988
2989
2990
d_m3Op(ResumePayload)
2991
0
{
2992
0
    IM3Runtime      runtime = m3MemRuntime(_mem);
2993
2994
    // The payload comes from the suspend; the reference is to the whole of what
2995
    // was captured, which is not the same continuation once the suspend has
2996
    // travelled out through a resume that had nothing to say about its tag.
2997
0
    IM3Continuation cont = runtime->suspendedContinuation;
2998
0
    cont->type = immediate(IM3FuncType);
2999
3000
0
    u32 numArgs = immediate(u32);
3001
0
    for (u32 i = 0; i < numArgs; ++i) {
3002
0
        i32 offset = immediate(i32);
3003
0
        u32 is64 = immediate(u32);
3004
0
        u64 val = (i < runtime->numSuspendPayload) ? runtime->suspendPayload[i] : 0;
3005
0
        if (is64) {
3006
0
            *(u64*)(_sp + offset) = val;
3007
0
        } else {
3008
0
            *(u32*)(_sp + offset) = (u32)val;
3009
0
        }
3010
0
    }
3011
3012
0
    i32 contOffset = immediate(i32);
3013
0
    if (contOffset >= 0) {
3014
0
        *(IM3Continuation*)(_sp + contOffset) = cont;
3015
0
    }
3016
3017
0
    nextOp();
3018
0
}
3019
3020
3021
// switch is a suspend that names its own replacement. Rather than run the
3022
// peer here - which would leave this native frame owning a continuation it is
3023
// no longer running - it suspends the current continuation the ordinary way and
3024
// hands the peer to the resume that installed the matching (on $e switch)
3025
// handler. That resume is the delimiter the proposal asks for, and it is the
3026
// frame that should be tracking whatever is running under it.
3027
d_m3Op(Switch)
3028
0
{
3029
0
    IM3Runtime      runtime = m3MemRuntime(_mem);
3030
0
    IM3Continuation cont = runtime->activeContinuation;
3031
3032
0
    if (M3_UNLIKELY(not cont)) {
3033
0
        newTrap(m3Err_trapUnhandledControlTag);
3034
0
    }
3035
3036
0
    skip_immediate(IM3FuncType);
3037
3038
0
    IM3Tag          tag = immediate(IM3Tag);
3039
0
    i32             targetSlot = immediate(i32);
3040
3041
0
    IM3Continuation target = *(IM3Continuation*)(_sp + targetSlot);
3042
3043
0
    if (M3_UNLIKELY(not target)) {
3044
0
        newTrap(m3Err_trapNullContinuationRef);
3045
0
    }
3046
0
    if (M3_UNLIKELY(target->state == cont_consumed or target->state == cont_running)) {
3047
0
        newTrap(m3Err_trapContinuationConsumed);
3048
0
    }
3049
3050
0
    IM3Continuation handlerCont = FindHandler(cont, tag, 1, NULL);
3051
3052
0
    if (M3_UNLIKELY(not handlerCont)) {
3053
0
        newTrap(m3Err_trapUnhandledControlTag);
3054
0
    }
3055
3056
    // the peer's arguments, and after them the room for the continuation
3057
    // reference the resume will write once this one is safely suspended
3058
0
    u32 numArgs = immediate(u32);
3059
3060
0
    runtime->numSuspendPayload = numArgs;
3061
3062
0
    for (u32 i = 0; i < numArgs; ++i) {
3063
0
        i32 argSlot = immediate(i32);
3064
0
        u32 is64 = immediate(u32);
3065
3066
0
        runtime->suspendPayload[i] = is64 ? *(u64*)(_sp + argSlot) : (u64) * (u32*)(_sp + argSlot);
3067
0
        runtime->suspendPayloadIs64[i] = is64;
3068
0
    }
3069
3070
    // where the values come back to, when something switches into this one
3071
0
    u32 numResults = immediate(u32);
3072
3073
0
    cont->numSuspendResults = numResults;
3074
3075
0
    for (u32 i = 0; i < numResults; ++i) {
3076
0
        cont->suspendResultOffsets[i] = immediate(i32);
3077
0
        cont->suspendResultIs64[i] = immediate(u32);
3078
0
    }
3079
3080
0
    ClearSuspendResults(cont, _sp);
3081
3082
0
    runtime->suspendStubPC = NULL;
3083
0
    runtime->suspendHandlerCont = handlerCont;
3084
0
    runtime->switchTarget = target;
3085
0
    runtime->suspendTag = tag;
3086
3087
0
    cont->pc = _pc;
3088
0
    cont->suspendPoint = safepoint_suspend;
3089
0
    cont->sp = _sp;
3090
0
    cont->r0 = _r0;
3091
0
#  if d_m3HasFloat
3092
0
    cont->fp0 = _fp0;
3093
0
#  endif
3094
3095
0
    return m3Err_continuationSuspended;
3096
0
}
3097
3098
3099
#endif // d_m3HasStackSwitching
3100
3101
3102
d_m3Op(Branch)
3103
1.43M
{
3104
1.43M
    jumpOp(*_pc);
3105
1.43M
}
3106
3107
3108
d_m3Op(If_r)
3109
8.85M
{
3110
8.85M
    i32  condition = (i32)_r0;
3111
3112
8.85M
    pc_t elsePC = immediate(pc_t);
3113
3114
8.85M
    if (condition) {
3115
5.78M
        nextOp();
3116
5.78M
    } else {
3117
3.07M
        jumpOp(elsePC);
3118
3.07M
    }
3119
8.85M
}
3120
3121
3122
d_m3Op(If_s)
3123
9.99M
{
3124
9.99M
    i32  condition = slot(i32);
3125
3126
9.99M
    pc_t elsePC = immediate(pc_t);
3127
3128
9.99M
    if (condition) {
3129
9.38M
        nextOp();
3130
9.38M
    } else {
3131
604k
        jumpOp(elsePC);
3132
604k
    }
3133
9.99M
}
3134
3135
3136
d_m3Op(BranchTable)
3137
344k
{
3138
344k
    u32   branchIndex = slot(u32);           // branch index is always in a slot
3139
344k
    u32   numTargets = immediate(u32);
3140
3141
344k
    pc_t* branches = (pc_t*)_pc;
3142
3143
344k
    if (branchIndex > numTargets) {
3144
224k
        branchIndex = numTargets; // the default index
3145
224k
    }
3146
3147
344k
    jumpOp(branches[branchIndex]);
3148
344k
}
3149
3150
3151
#define d_m3SetRegisterSetSlot(TYPE, REG) \
3152
2.33M
d_m3Op  (SetRegister_##TYPE)            \
3153
2.33M
{                                       \
3154
2.33M
    TYPE * src = slot_ptr (TYPE);       \
3155
2.33M
    d_m3PreloadNext ();                 \
3156
2.33M
    REG = * src;                        \
3157
2.33M
    nextOpPreloaded ();                 \
3158
2.33M
}                                       \
m3_compile.c:op_SetRegister_i32
Line
Count
Source
3152
1.58M
d_m3Op  (SetRegister_##TYPE)            \
3153
1.58M
{                                       \
3154
1.58M
    TYPE * src = slot_ptr (TYPE);       \
3155
1.58M
    d_m3PreloadNext ();                 \
3156
1.58M
    REG = * src;                        \
3157
1.58M
    nextOpPreloaded ();                 \
3158
1.58M
}                                       \
m3_compile.c:op_SetRegister_i64
Line
Count
Source
3152
677k
d_m3Op  (SetRegister_##TYPE)            \
3153
677k
{                                       \
3154
677k
    TYPE * src = slot_ptr (TYPE);       \
3155
677k
    d_m3PreloadNext ();                 \
3156
677k
    REG = * src;                        \
3157
677k
    nextOpPreloaded ();                 \
3158
677k
}                                       \
m3_compile.c:op_SetRegister_f32
Line
Count
Source
3152
70.5k
d_m3Op  (SetRegister_##TYPE)            \
3153
70.5k
{                                       \
3154
70.5k
    TYPE * src = slot_ptr (TYPE);       \
3155
70.5k
    d_m3PreloadNext ();                 \
3156
70.5k
    REG = * src;                        \
3157
70.5k
    nextOpPreloaded ();                 \
3158
70.5k
}                                       \
m3_compile.c:op_SetRegister_f64
Line
Count
Source
3152
401
d_m3Op  (SetRegister_##TYPE)            \
3153
401
{                                       \
3154
401
    TYPE * src = slot_ptr (TYPE);       \
3155
401
    d_m3PreloadNext ();                 \
3156
401
    REG = * src;                        \
3157
401
    nextOpPreloaded ();                 \
3158
401
}                                       \
3159
                                        \
3160
71.6M
d_m3Op (SetSlot_##TYPE)                 \
3161
71.6M
{                                       \
3162
71.6M
    TYPE * dst = slot_ptr (TYPE);       \
3163
71.6M
    d_m3PreloadNext ();                 \
3164
71.6M
    * dst = (TYPE) REG;                 \
3165
71.6M
    nextOpPreloaded ();                 \
3166
71.6M
}                                       \
m3_compile.c:op_SetSlot_i32
Line
Count
Source
3160
38.6M
d_m3Op (SetSlot_##TYPE)                 \
3161
38.6M
{                                       \
3162
38.6M
    TYPE * dst = slot_ptr (TYPE);       \
3163
38.6M
    d_m3PreloadNext ();                 \
3164
38.6M
    * dst = (TYPE) REG;                 \
3165
38.6M
    nextOpPreloaded ();                 \
3166
38.6M
}                                       \
m3_compile.c:op_SetSlot_i64
Line
Count
Source
3160
18.1M
d_m3Op (SetSlot_##TYPE)                 \
3161
18.1M
{                                       \
3162
18.1M
    TYPE * dst = slot_ptr (TYPE);       \
3163
18.1M
    d_m3PreloadNext ();                 \
3164
18.1M
    * dst = (TYPE) REG;                 \
3165
18.1M
    nextOpPreloaded ();                 \
3166
18.1M
}                                       \
m3_compile.c:op_SetSlot_f32
Line
Count
Source
3160
6.48M
d_m3Op (SetSlot_##TYPE)                 \
3161
6.48M
{                                       \
3162
6.48M
    TYPE * dst = slot_ptr (TYPE);       \
3163
6.48M
    d_m3PreloadNext ();                 \
3164
6.48M
    * dst = (TYPE) REG;                 \
3165
6.48M
    nextOpPreloaded ();                 \
3166
6.48M
}                                       \
m3_compile.c:op_SetSlot_f64
Line
Count
Source
3160
8.33M
d_m3Op (SetSlot_##TYPE)                 \
3161
8.33M
{                                       \
3162
8.33M
    TYPE * dst = slot_ptr (TYPE);       \
3163
8.33M
    d_m3PreloadNext ();                 \
3164
8.33M
    * dst = (TYPE) REG;                 \
3165
8.33M
    nextOpPreloaded ();                 \
3166
8.33M
}                                       \
3167
                                        \
3168
1.00M
d_m3Op (PreserveSetSlot_##TYPE)         \
3169
1.00M
{                                       \
3170
1.00M
    TYPE * stack     = slot_ptr (TYPE); \
3171
1.00M
    TYPE * preserve  = slot_ptr (TYPE); \
3172
1.00M
    d_m3PreloadNext ();                 \
3173
1.00M
                                        \
3174
1.00M
    * preserve = * stack;               \
3175
1.00M
    * stack = (TYPE) REG;               \
3176
1.00M
                                        \
3177
1.00M
    nextOpPreloaded ();                 \
3178
1.00M
}
m3_compile.c:op_PreserveSetSlot_i32
Line
Count
Source
3168
318k
d_m3Op (PreserveSetSlot_##TYPE)         \
3169
318k
{                                       \
3170
318k
    TYPE * stack     = slot_ptr (TYPE); \
3171
318k
    TYPE * preserve  = slot_ptr (TYPE); \
3172
318k
    d_m3PreloadNext ();                 \
3173
318k
                                        \
3174
318k
    * preserve = * stack;               \
3175
318k
    * stack = (TYPE) REG;               \
3176
318k
                                        \
3177
318k
    nextOpPreloaded ();                 \
3178
318k
}
m3_compile.c:op_PreserveSetSlot_i64
Line
Count
Source
3168
90.1k
d_m3Op (PreserveSetSlot_##TYPE)         \
3169
90.1k
{                                       \
3170
90.1k
    TYPE * stack     = slot_ptr (TYPE); \
3171
90.1k
    TYPE * preserve  = slot_ptr (TYPE); \
3172
90.1k
    d_m3PreloadNext ();                 \
3173
90.1k
                                        \
3174
90.1k
    * preserve = * stack;               \
3175
90.1k
    * stack = (TYPE) REG;               \
3176
90.1k
                                        \
3177
90.1k
    nextOpPreloaded ();                 \
3178
90.1k
}
m3_compile.c:op_PreserveSetSlot_f32
Line
Count
Source
3168
264k
d_m3Op (PreserveSetSlot_##TYPE)         \
3169
264k
{                                       \
3170
264k
    TYPE * stack     = slot_ptr (TYPE); \
3171
264k
    TYPE * preserve  = slot_ptr (TYPE); \
3172
264k
    d_m3PreloadNext ();                 \
3173
264k
                                        \
3174
264k
    * preserve = * stack;               \
3175
264k
    * stack = (TYPE) REG;               \
3176
264k
                                        \
3177
264k
    nextOpPreloaded ();                 \
3178
264k
}
m3_compile.c:op_PreserveSetSlot_f64
Line
Count
Source
3168
328k
d_m3Op (PreserveSetSlot_##TYPE)         \
3169
328k
{                                       \
3170
328k
    TYPE * stack     = slot_ptr (TYPE); \
3171
328k
    TYPE * preserve  = slot_ptr (TYPE); \
3172
328k
    d_m3PreloadNext ();                 \
3173
328k
                                        \
3174
328k
    * preserve = * stack;               \
3175
328k
    * stack = (TYPE) REG;               \
3176
328k
                                        \
3177
328k
    nextOpPreloaded ();                 \
3178
328k
}
3179
3180
d_m3SetRegisterSetSlot(i32, _r0)
3181
d_m3SetRegisterSetSlot(i64, _r0)
3182
#if d_m3HasFloat
3183
d_m3SetRegisterSetSlot(f32, _fp0)
3184
d_m3SetRegisterSetSlot(f64, _fp0)
3185
#endif
3186
3187
d_m3Op(CopySlot_32)
3188
4.07M
{
3189
4.07M
    u32* dst = slot_ptr(u32);
3190
4.07M
    u32* src = slot_ptr(u32);
3191
4.07M
    d_m3PreloadNext();
3192
3193
4.07M
    *dst = *src;
3194
3195
4.07M
    nextOpPreloaded();
3196
4.07M
}
3197
3198
3199
d_m3Op(PreserveCopySlot_32)
3200
617k
{
3201
617k
    u32* dest = slot_ptr(u32);
3202
617k
    u32* src = slot_ptr(u32);
3203
617k
    u32* preserve = slot_ptr(u32);
3204
617k
    d_m3PreloadNext();
3205
3206
617k
    *preserve = *dest;
3207
617k
    *dest = *src;
3208
3209
617k
    nextOpPreloaded();
3210
617k
}
3211
3212
3213
d_m3Op(CopySlot_64)
3214
3.22M
{
3215
3.22M
    u64* dst = slot_ptr(u64);
3216
3.22M
    u64* src = slot_ptr(u64);
3217
3.22M
    d_m3PreloadNext();
3218
3219
3.22M
    *dst = *src;                  // printf ("copy: %p <- %" PRIi64 " <- %p\n", dst, * dst, src);
3220
3221
3.22M
    nextOpPreloaded();
3222
3.22M
}
3223
3224
3225
d_m3Op(PreserveCopySlot_64)
3226
1.01M
{
3227
1.01M
    u64* dest = slot_ptr(u64);
3228
1.01M
    u64* src = slot_ptr(u64);
3229
1.01M
    u64* preserve = slot_ptr(u64);
3230
1.01M
    d_m3PreloadNext();
3231
3232
1.01M
    *preserve = *dest;
3233
1.01M
    *dest = *src;
3234
3235
1.01M
    nextOpPreloaded();
3236
1.01M
}
3237
3238
3239
#if d_m3EnableOpTracing
3240
//--------------------------------------------------------------------------------------------------------
3241
d_m3Op(DumpStack)
3242
{
3243
    u32         opcodeIndex = immediate(u32);
3244
    u32         stackHeight = immediate(u32);
3245
    IM3Function function = immediate(IM3Function);
3246
3247
    cstr_t      funcName = (function) ? m3_GetFunctionName(function) : "";
3248
3249
    printf(" %4d ", opcodeIndex);
3250
    printf(" %-25s     r0: 0x%016" PRIx64 "  i:%" PRIi64 "  u:%" PRIu64 "\n", funcName, _r0, _r0, _r0);
3251
#  if d_m3HasFloat
3252
    printf("                                    fp0: %" PRIf64 "\n", _fp0);
3253
#  endif
3254
    m3stack_t sp = _sp;
3255
3256
    for (u32 i = 0; i < stackHeight; ++i) {
3257
        cstr_t kind = "";
3258
3259
        printf("%p  %5s  %2d: 0x%" PRIx64 "  i:%" PRIi64 "\n", sp, kind, i, (u64) * (sp), (i64) * (sp));
3260
3261
        ++sp;
3262
    }
3263
    printf("---------------------------------------------------------------------------------------------------------\n");
3264
3265
    nextOpDirect();
3266
}
3267
#endif
3268
3269
3270
#define d_m3Select_i(TYPE, REG)                 \
3271
1.25M
d_m3Op  (Select_##TYPE##_rss)                   \
3272
1.25M
{                                               \
3273
1.25M
    i32 condition = (i32) _r0;                  \
3274
1.25M
                                                \
3275
1.25M
    TYPE operand2 = slot (TYPE);                \
3276
1.25M
    TYPE operand1 = slot (TYPE);                \
3277
1.25M
                                                \
3278
1.25M
    REG = (condition) ? operand1 : operand2;    \
3279
1.25M
                                                \
3280
1.25M
    nextOp ();                                  \
3281
1.25M
}                                               \
m3_compile.c:op_Select_i32_rss
Line
Count
Source
3271
793k
d_m3Op  (Select_##TYPE##_rss)                   \
3272
793k
{                                               \
3273
793k
    i32 condition = (i32) _r0;                  \
3274
793k
                                                \
3275
793k
    TYPE operand2 = slot (TYPE);                \
3276
793k
    TYPE operand1 = slot (TYPE);                \
3277
793k
                                                \
3278
793k
    REG = (condition) ? operand1 : operand2;    \
3279
793k
                                                \
3280
793k
    nextOp ();                                  \
3281
793k
}                                               \
m3_compile.c:op_Select_i64_rss
Line
Count
Source
3271
464k
d_m3Op  (Select_##TYPE##_rss)                   \
3272
464k
{                                               \
3273
464k
    i32 condition = (i32) _r0;                  \
3274
464k
                                                \
3275
464k
    TYPE operand2 = slot (TYPE);                \
3276
464k
    TYPE operand1 = slot (TYPE);                \
3277
464k
                                                \
3278
464k
    REG = (condition) ? operand1 : operand2;    \
3279
464k
                                                \
3280
464k
    nextOp ();                                  \
3281
464k
}                                               \
3282
                                                \
3283
877k
d_m3Op  (Select_##TYPE##_srs)                   \
3284
877k
{                                               \
3285
877k
    i32 condition = slot (i32);                 \
3286
877k
                                                \
3287
877k
    TYPE operand2 = (TYPE) REG;                 \
3288
877k
    TYPE operand1 = slot (TYPE);                \
3289
877k
                                                \
3290
877k
    REG = (condition) ? operand1 : operand2;    \
3291
877k
                                                \
3292
877k
    nextOp ();                                  \
3293
877k
}                                               \
m3_compile.c:op_Select_i32_srs
Line
Count
Source
3283
680k
d_m3Op  (Select_##TYPE##_srs)                   \
3284
680k
{                                               \
3285
680k
    i32 condition = slot (i32);                 \
3286
680k
                                                \
3287
680k
    TYPE operand2 = (TYPE) REG;                 \
3288
680k
    TYPE operand1 = slot (TYPE);                \
3289
680k
                                                \
3290
680k
    REG = (condition) ? operand1 : operand2;    \
3291
680k
                                                \
3292
680k
    nextOp ();                                  \
3293
680k
}                                               \
m3_compile.c:op_Select_i64_srs
Line
Count
Source
3283
196k
d_m3Op  (Select_##TYPE##_srs)                   \
3284
196k
{                                               \
3285
196k
    i32 condition = slot (i32);                 \
3286
196k
                                                \
3287
196k
    TYPE operand2 = (TYPE) REG;                 \
3288
196k
    TYPE operand1 = slot (TYPE);                \
3289
196k
                                                \
3290
196k
    REG = (condition) ? operand1 : operand2;    \
3291
196k
                                                \
3292
196k
    nextOp ();                                  \
3293
196k
}                                               \
3294
                                                \
3295
1.02M
d_m3Op  (Select_##TYPE##_ssr)                   \
3296
1.02M
{                                               \
3297
1.02M
    i32 condition = slot (i32);                 \
3298
1.02M
                                                \
3299
1.02M
    TYPE operand2 = slot (TYPE);                \
3300
1.02M
    TYPE operand1 = (TYPE) REG;                 \
3301
1.02M
                                                \
3302
1.02M
    REG = (condition) ? operand1 : operand2;    \
3303
1.02M
                                                \
3304
1.02M
    nextOp ();                                  \
3305
1.02M
}                                               \
m3_compile.c:op_Select_i32_ssr
Line
Count
Source
3295
621k
d_m3Op  (Select_##TYPE##_ssr)                   \
3296
621k
{                                               \
3297
621k
    i32 condition = slot (i32);                 \
3298
621k
                                                \
3299
621k
    TYPE operand2 = slot (TYPE);                \
3300
621k
    TYPE operand1 = (TYPE) REG;                 \
3301
621k
                                                \
3302
621k
    REG = (condition) ? operand1 : operand2;    \
3303
621k
                                                \
3304
621k
    nextOp ();                                  \
3305
621k
}                                               \
m3_compile.c:op_Select_i64_ssr
Line
Count
Source
3295
405k
d_m3Op  (Select_##TYPE##_ssr)                   \
3296
405k
{                                               \
3297
405k
    i32 condition = slot (i32);                 \
3298
405k
                                                \
3299
405k
    TYPE operand2 = slot (TYPE);                \
3300
405k
    TYPE operand1 = (TYPE) REG;                 \
3301
405k
                                                \
3302
405k
    REG = (condition) ? operand1 : operand2;    \
3303
405k
                                                \
3304
405k
    nextOp ();                                  \
3305
405k
}                                               \
3306
                                                \
3307
1.53M
d_m3Op  (Select_##TYPE##_sss)                   \
3308
1.53M
{                                               \
3309
1.53M
    i32 condition = slot (i32);                 \
3310
1.53M
                                                \
3311
1.53M
    TYPE operand2 = slot (TYPE);                \
3312
1.53M
    TYPE operand1 = slot (TYPE);                \
3313
1.53M
                                                \
3314
1.53M
    REG = (condition) ? operand1 : operand2;    \
3315
1.53M
                                                \
3316
1.53M
    nextOp ();                                  \
3317
1.53M
}
m3_compile.c:op_Select_i32_sss
Line
Count
Source
3307
1.10M
d_m3Op  (Select_##TYPE##_sss)                   \
3308
1.10M
{                                               \
3309
1.10M
    i32 condition = slot (i32);                 \
3310
1.10M
                                                \
3311
1.10M
    TYPE operand2 = slot (TYPE);                \
3312
1.10M
    TYPE operand1 = slot (TYPE);                \
3313
1.10M
                                                \
3314
1.10M
    REG = (condition) ? operand1 : operand2;    \
3315
1.10M
                                                \
3316
1.10M
    nextOp ();                                  \
3317
1.10M
}
m3_compile.c:op_Select_i64_sss
Line
Count
Source
3307
434k
d_m3Op  (Select_##TYPE##_sss)                   \
3308
434k
{                                               \
3309
434k
    i32 condition = slot (i32);                 \
3310
434k
                                                \
3311
434k
    TYPE operand2 = slot (TYPE);                \
3312
434k
    TYPE operand1 = slot (TYPE);                \
3313
434k
                                                \
3314
434k
    REG = (condition) ? operand1 : operand2;    \
3315
434k
                                                \
3316
434k
    nextOp ();                                  \
3317
434k
}
3318
3319
3320
d_m3Select_i(i32, _r0)
3321
d_m3Select_i(i64, _r0)
3322
3323
3324
#define d_m3Select_f(TYPE, REG, LABEL, SELECTOR)  \
3325
1.50M
d_m3Op  (Select_##TYPE##_##LABEL##ss)           \
3326
1.50M
{                                               \
3327
1.50M
    i32 condition = (i32) SELECTOR;             \
3328
1.50M
                                                \
3329
1.50M
    TYPE operand2 = slot (TYPE);                \
3330
1.50M
    TYPE operand1 = slot (TYPE);                \
3331
1.50M
                                                \
3332
1.50M
    REG = (condition) ? operand1 : operand2;    \
3333
1.50M
                                                \
3334
1.50M
    nextOp ();                                  \
3335
1.50M
}                                               \
m3_compile.c:op_Select_f32_sss
Line
Count
Source
3325
511k
d_m3Op  (Select_##TYPE##_##LABEL##ss)           \
3326
511k
{                                               \
3327
511k
    i32 condition = (i32) SELECTOR;             \
3328
511k
                                                \
3329
511k
    TYPE operand2 = slot (TYPE);                \
3330
511k
    TYPE operand1 = slot (TYPE);                \
3331
511k
                                                \
3332
511k
    REG = (condition) ? operand1 : operand2;    \
3333
511k
                                                \
3334
511k
    nextOp ();                                  \
3335
511k
}                                               \
m3_compile.c:op_Select_f32_rss
Line
Count
Source
3325
415k
d_m3Op  (Select_##TYPE##_##LABEL##ss)           \
3326
415k
{                                               \
3327
415k
    i32 condition = (i32) SELECTOR;             \
3328
415k
                                                \
3329
415k
    TYPE operand2 = slot (TYPE);                \
3330
415k
    TYPE operand1 = slot (TYPE);                \
3331
415k
                                                \
3332
415k
    REG = (condition) ? operand1 : operand2;    \
3333
415k
                                                \
3334
415k
    nextOp ();                                  \
3335
415k
}                                               \
m3_compile.c:op_Select_f64_sss
Line
Count
Source
3325
252k
d_m3Op  (Select_##TYPE##_##LABEL##ss)           \
3326
252k
{                                               \
3327
252k
    i32 condition = (i32) SELECTOR;             \
3328
252k
                                                \
3329
252k
    TYPE operand2 = slot (TYPE);                \
3330
252k
    TYPE operand1 = slot (TYPE);                \
3331
252k
                                                \
3332
252k
    REG = (condition) ? operand1 : operand2;    \
3333
252k
                                                \
3334
252k
    nextOp ();                                  \
3335
252k
}                                               \
m3_compile.c:op_Select_f64_rss
Line
Count
Source
3325
321k
d_m3Op  (Select_##TYPE##_##LABEL##ss)           \
3326
321k
{                                               \
3327
321k
    i32 condition = (i32) SELECTOR;             \
3328
321k
                                                \
3329
321k
    TYPE operand2 = slot (TYPE);                \
3330
321k
    TYPE operand1 = slot (TYPE);                \
3331
321k
                                                \
3332
321k
    REG = (condition) ? operand1 : operand2;    \
3333
321k
                                                \
3334
321k
    nextOp ();                                  \
3335
321k
}                                               \
3336
                                                \
3337
908k
d_m3Op  (Select_##TYPE##_##LABEL##rs)           \
3338
908k
{                                               \
3339
908k
    i32 condition = (i32) SELECTOR;             \
3340
908k
                                                \
3341
908k
    TYPE operand2 = (TYPE) REG;                 \
3342
908k
    TYPE operand1 = slot (TYPE);                \
3343
908k
                                                \
3344
908k
    REG = (condition) ? operand1 : operand2;    \
3345
908k
                                                \
3346
908k
    nextOp ();                                  \
3347
908k
}                                               \
m3_compile.c:op_Select_f32_srs
Line
Count
Source
3337
243k
d_m3Op  (Select_##TYPE##_##LABEL##rs)           \
3338
243k
{                                               \
3339
243k
    i32 condition = (i32) SELECTOR;             \
3340
243k
                                                \
3341
243k
    TYPE operand2 = (TYPE) REG;                 \
3342
243k
    TYPE operand1 = slot (TYPE);                \
3343
243k
                                                \
3344
243k
    REG = (condition) ? operand1 : operand2;    \
3345
243k
                                                \
3346
243k
    nextOp ();                                  \
3347
243k
}                                               \
m3_compile.c:op_Select_f32_rrs
Line
Count
Source
3337
315k
d_m3Op  (Select_##TYPE##_##LABEL##rs)           \
3338
315k
{                                               \
3339
315k
    i32 condition = (i32) SELECTOR;             \
3340
315k
                                                \
3341
315k
    TYPE operand2 = (TYPE) REG;                 \
3342
315k
    TYPE operand1 = slot (TYPE);                \
3343
315k
                                                \
3344
315k
    REG = (condition) ? operand1 : operand2;    \
3345
315k
                                                \
3346
315k
    nextOp ();                                  \
3347
315k
}                                               \
m3_compile.c:op_Select_f64_srs
Line
Count
Source
3337
133k
d_m3Op  (Select_##TYPE##_##LABEL##rs)           \
3338
133k
{                                               \
3339
133k
    i32 condition = (i32) SELECTOR;             \
3340
133k
                                                \
3341
133k
    TYPE operand2 = (TYPE) REG;                 \
3342
133k
    TYPE operand1 = slot (TYPE);                \
3343
133k
                                                \
3344
133k
    REG = (condition) ? operand1 : operand2;    \
3345
133k
                                                \
3346
133k
    nextOp ();                                  \
3347
133k
}                                               \
m3_compile.c:op_Select_f64_rrs
Line
Count
Source
3337
215k
d_m3Op  (Select_##TYPE##_##LABEL##rs)           \
3338
215k
{                                               \
3339
215k
    i32 condition = (i32) SELECTOR;             \
3340
215k
                                                \
3341
215k
    TYPE operand2 = (TYPE) REG;                 \
3342
215k
    TYPE operand1 = slot (TYPE);                \
3343
215k
                                                \
3344
215k
    REG = (condition) ? operand1 : operand2;    \
3345
215k
                                                \
3346
215k
    nextOp ();                                  \
3347
215k
}                                               \
3348
                                                \
3349
968k
d_m3Op  (Select_##TYPE##_##LABEL##sr)           \
3350
968k
{                                               \
3351
968k
    i32 condition = (i32) SELECTOR;             \
3352
968k
                                                \
3353
968k
    TYPE operand2 = slot (TYPE);                \
3354
968k
    TYPE operand1 = (TYPE) REG;                 \
3355
968k
                                                \
3356
968k
    REG = (condition) ? operand1 : operand2;    \
3357
968k
                                                \
3358
968k
    nextOp ();                                  \
3359
968k
}
m3_compile.c:op_Select_f32_ssr
Line
Count
Source
3349
189k
d_m3Op  (Select_##TYPE##_##LABEL##sr)           \
3350
189k
{                                               \
3351
189k
    i32 condition = (i32) SELECTOR;             \
3352
189k
                                                \
3353
189k
    TYPE operand2 = slot (TYPE);                \
3354
189k
    TYPE operand1 = (TYPE) REG;                 \
3355
189k
                                                \
3356
189k
    REG = (condition) ? operand1 : operand2;    \
3357
189k
                                                \
3358
189k
    nextOp ();                                  \
3359
189k
}
m3_compile.c:op_Select_f32_rsr
Line
Count
Source
3349
392k
d_m3Op  (Select_##TYPE##_##LABEL##sr)           \
3350
392k
{                                               \
3351
392k
    i32 condition = (i32) SELECTOR;             \
3352
392k
                                                \
3353
392k
    TYPE operand2 = slot (TYPE);                \
3354
392k
    TYPE operand1 = (TYPE) REG;                 \
3355
392k
                                                \
3356
392k
    REG = (condition) ? operand1 : operand2;    \
3357
392k
                                                \
3358
392k
    nextOp ();                                  \
3359
392k
}
m3_compile.c:op_Select_f64_ssr
Line
Count
Source
3349
214k
d_m3Op  (Select_##TYPE##_##LABEL##sr)           \
3350
214k
{                                               \
3351
214k
    i32 condition = (i32) SELECTOR;             \
3352
214k
                                                \
3353
214k
    TYPE operand2 = slot (TYPE);                \
3354
214k
    TYPE operand1 = (TYPE) REG;                 \
3355
214k
                                                \
3356
214k
    REG = (condition) ? operand1 : operand2;    \
3357
214k
                                                \
3358
214k
    nextOp ();                                  \
3359
214k
}
m3_compile.c:op_Select_f64_rsr
Line
Count
Source
3349
172k
d_m3Op  (Select_##TYPE##_##LABEL##sr)           \
3350
172k
{                                               \
3351
172k
    i32 condition = (i32) SELECTOR;             \
3352
172k
                                                \
3353
172k
    TYPE operand2 = slot (TYPE);                \
3354
172k
    TYPE operand1 = (TYPE) REG;                 \
3355
172k
                                                \
3356
172k
    REG = (condition) ? operand1 : operand2;    \
3357
172k
                                                \
3358
172k
    nextOp ();                                  \
3359
172k
}
3360
3361
#if d_m3HasFloat
3362
d_m3Select_f(f32, _fp0, r, _r0)
3363
d_m3Select_f(f32, _fp0, s, slot(i32))
3364
3365
d_m3Select_f(f64, _fp0, r, _r0)
3366
d_m3Select_f(f64, _fp0, s, slot(i32))
3367
#endif
3368
3369
d_m3Op(Return)
3370
2.61k
{
3371
2.61k
    m3StackCheck();
3372
2.61k
    return m3Err_none;
3373
2.61k
}
3374
3375
3376
d_m3Op(BranchIf_r)
3377
455k
{
3378
455k
    i32  condition = (i32)_r0;
3379
455k
    pc_t branch = immediate(pc_t);
3380
3381
455k
    if (condition) {
3382
364k
        jumpOp(branch);
3383
364k
    } else {
3384
90.1k
        nextOp();
3385
90.1k
    }
3386
455k
}
3387
3388
3389
d_m3Op(BranchIf_s)
3390
522k
{
3391
522k
    i32  condition = slot(i32);
3392
522k
    pc_t branch = immediate(pc_t);
3393
3394
522k
    if (condition) {
3395
138k
        jumpOp(branch);
3396
383k
    } else {
3397
383k
        nextOp();
3398
383k
    }
3399
522k
}
3400
3401
#if d_m3FuseBranch
3402
3403
// fused compare+branch and compare+if: a compare retro-patched by the compiler when a br_if or if
3404
// immediately consumes its result. operand shapes and immediate order match the plain compare
3405
// (_rs/_sr/_ss); the branch/else target pointer is the last immediate.
3406
#  define d_m3FusedCmpBranch(TYPE, NAME, OPER)                \
3407
  d_m3Op(TYPE##_BranchIf_##NAME##_rs)                         \
3408
1.61M
  {                                                           \
3409
1.61M
      TYPE operand = slot (TYPE);                             \
3410
1.61M
      pc_t branch  = immediate (pc_t);                        \
3411
1.61M
      if (operand OPER ((TYPE) _r0))                          \
3412
1.61M
          jumpOp (branch);                                    \
3413
1.61M
      else nextOp ();                                         \
3414
1.61M
  }                                                           \
m3_compile.c:op_i32_BranchIf_Equal_rs
Line
Count
Source
3408
176k
  {                                                           \
3409
176k
      TYPE operand = slot (TYPE);                             \
3410
176k
      pc_t branch  = immediate (pc_t);                        \
3411
176k
      if (operand OPER ((TYPE) _r0))                          \
3412
176k
          jumpOp (branch);                                    \
3413
176k
      else nextOp ();                                         \
3414
176k
  }                                                           \
m3_compile.c:op_i32_BranchIf_NotEqual_rs
Line
Count
Source
3408
228k
  {                                                           \
3409
228k
      TYPE operand = slot (TYPE);                             \
3410
228k
      pc_t branch  = immediate (pc_t);                        \
3411
228k
      if (operand OPER ((TYPE) _r0))                          \
3412
228k
          jumpOp (branch);                                    \
3413
228k
      else nextOp ();                                         \
3414
228k
  }                                                           \
m3_compile.c:op_i32_BranchIf_LessThan_rs
Line
Count
Source
3408
78.6k
  {                                                           \
3409
78.6k
      TYPE operand = slot (TYPE);                             \
3410
78.6k
      pc_t branch  = immediate (pc_t);                        \
3411
78.6k
      if (operand OPER ((TYPE) _r0))                          \
3412
78.6k
          jumpOp (branch);                                    \
3413
78.6k
      else nextOp ();                                         \
3414
78.6k
  }                                                           \
m3_compile.c:op_u32_BranchIf_LessThan_rs
Line
Count
Source
3408
102k
  {                                                           \
3409
102k
      TYPE operand = slot (TYPE);                             \
3410
102k
      pc_t branch  = immediate (pc_t);                        \
3411
102k
      if (operand OPER ((TYPE) _r0))                          \
3412
102k
          jumpOp (branch);                                    \
3413
102k
      else nextOp ();                                         \
3414
102k
  }                                                           \
m3_compile.c:op_i32_BranchIf_GreaterThan_rs
Line
Count
Source
3408
146k
  {                                                           \
3409
146k
      TYPE operand = slot (TYPE);                             \
3410
146k
      pc_t branch  = immediate (pc_t);                        \
3411
146k
      if (operand OPER ((TYPE) _r0))                          \
3412
146k
          jumpOp (branch);                                    \
3413
146k
      else nextOp ();                                         \
3414
146k
  }                                                           \
m3_compile.c:op_u32_BranchIf_GreaterThan_rs
Line
Count
Source
3408
107k
  {                                                           \
3409
107k
      TYPE operand = slot (TYPE);                             \
3410
107k
      pc_t branch  = immediate (pc_t);                        \
3411
107k
      if (operand OPER ((TYPE) _r0))                          \
3412
107k
          jumpOp (branch);                                    \
3413
107k
      else nextOp ();                                         \
3414
107k
  }                                                           \
m3_compile.c:op_i32_BranchIf_LessThanOrEqual_rs
Line
Count
Source
3408
201k
  {                                                           \
3409
201k
      TYPE operand = slot (TYPE);                             \
3410
201k
      pc_t branch  = immediate (pc_t);                        \
3411
201k
      if (operand OPER ((TYPE) _r0))                          \
3412
201k
          jumpOp (branch);                                    \
3413
201k
      else nextOp ();                                         \
3414
201k
  }                                                           \
m3_compile.c:op_u32_BranchIf_LessThanOrEqual_rs
Line
Count
Source
3408
116k
  {                                                           \
3409
116k
      TYPE operand = slot (TYPE);                             \
3410
116k
      pc_t branch  = immediate (pc_t);                        \
3411
116k
      if (operand OPER ((TYPE) _r0))                          \
3412
116k
          jumpOp (branch);                                    \
3413
116k
      else nextOp ();                                         \
3414
116k
  }                                                           \
m3_compile.c:op_i32_BranchIf_GreaterThanOrEqual_rs
Line
Count
Source
3408
305k
  {                                                           \
3409
305k
      TYPE operand = slot (TYPE);                             \
3410
305k
      pc_t branch  = immediate (pc_t);                        \
3411
305k
      if (operand OPER ((TYPE) _r0))                          \
3412
305k
          jumpOp (branch);                                    \
3413
305k
      else nextOp ();                                         \
3414
305k
  }                                                           \
m3_compile.c:op_u32_BranchIf_GreaterThanOrEqual_rs
Line
Count
Source
3408
153k
  {                                                           \
3409
153k
      TYPE operand = slot (TYPE);                             \
3410
153k
      pc_t branch  = immediate (pc_t);                        \
3411
153k
      if (operand OPER ((TYPE) _r0))                          \
3412
153k
          jumpOp (branch);                                    \
3413
153k
      else nextOp ();                                         \
3414
153k
  }                                                           \
3415
  d_m3Op(TYPE##_BranchIf_##NAME##_sr)                         \
3416
1.92M
  {                                                           \
3417
1.92M
      TYPE operand = slot (TYPE);                             \
3418
1.92M
      pc_t branch  = immediate (pc_t);                        \
3419
1.92M
      if (((TYPE) _r0) OPER operand)                          \
3420
1.92M
          jumpOp (branch);                                    \
3421
1.92M
      else nextOp ();                                         \
3422
1.92M
  }                                                           \
m3_compile.c:op_i32_BranchIf_LessThan_sr
Line
Count
Source
3416
180k
  {                                                           \
3417
180k
      TYPE operand = slot (TYPE);                             \
3418
180k
      pc_t branch  = immediate (pc_t);                        \
3419
180k
      if (((TYPE) _r0) OPER operand)                          \
3420
180k
          jumpOp (branch);                                    \
3421
180k
      else nextOp ();                                         \
3422
180k
  }                                                           \
m3_compile.c:op_u32_BranchIf_LessThan_sr
Line
Count
Source
3416
281k
  {                                                           \
3417
281k
      TYPE operand = slot (TYPE);                             \
3418
281k
      pc_t branch  = immediate (pc_t);                        \
3419
281k
      if (((TYPE) _r0) OPER operand)                          \
3420
281k
          jumpOp (branch);                                    \
3421
281k
      else nextOp ();                                         \
3422
281k
  }                                                           \
m3_compile.c:op_i32_BranchIf_GreaterThan_sr
Line
Count
Source
3416
265k
  {                                                           \
3417
265k
      TYPE operand = slot (TYPE);                             \
3418
265k
      pc_t branch  = immediate (pc_t);                        \
3419
265k
      if (((TYPE) _r0) OPER operand)                          \
3420
265k
          jumpOp (branch);                                    \
3421
265k
      else nextOp ();                                         \
3422
265k
  }                                                           \
m3_compile.c:op_u32_BranchIf_GreaterThan_sr
Line
Count
Source
3416
314k
  {                                                           \
3417
314k
      TYPE operand = slot (TYPE);                             \
3418
314k
      pc_t branch  = immediate (pc_t);                        \
3419
314k
      if (((TYPE) _r0) OPER operand)                          \
3420
314k
          jumpOp (branch);                                    \
3421
314k
      else nextOp ();                                         \
3422
314k
  }                                                           \
m3_compile.c:op_i32_BranchIf_LessThanOrEqual_sr
Line
Count
Source
3416
195k
  {                                                           \
3417
195k
      TYPE operand = slot (TYPE);                             \
3418
195k
      pc_t branch  = immediate (pc_t);                        \
3419
195k
      if (((TYPE) _r0) OPER operand)                          \
3420
195k
          jumpOp (branch);                                    \
3421
195k
      else nextOp ();                                         \
3422
195k
  }                                                           \
m3_compile.c:op_u32_BranchIf_LessThanOrEqual_sr
Line
Count
Source
3416
257k
  {                                                           \
3417
257k
      TYPE operand = slot (TYPE);                             \
3418
257k
      pc_t branch  = immediate (pc_t);                        \
3419
257k
      if (((TYPE) _r0) OPER operand)                          \
3420
257k
          jumpOp (branch);                                    \
3421
257k
      else nextOp ();                                         \
3422
257k
  }                                                           \
m3_compile.c:op_i32_BranchIf_GreaterThanOrEqual_sr
Line
Count
Source
3416
222k
  {                                                           \
3417
222k
      TYPE operand = slot (TYPE);                             \
3418
222k
      pc_t branch  = immediate (pc_t);                        \
3419
222k
      if (((TYPE) _r0) OPER operand)                          \
3420
222k
          jumpOp (branch);                                    \
3421
222k
      else nextOp ();                                         \
3422
222k
  }                                                           \
m3_compile.c:op_u32_BranchIf_GreaterThanOrEqual_sr
Line
Count
Source
3416
208k
  {                                                           \
3417
208k
      TYPE operand = slot (TYPE);                             \
3418
208k
      pc_t branch  = immediate (pc_t);                        \
3419
208k
      if (((TYPE) _r0) OPER operand)                          \
3420
208k
          jumpOp (branch);                                    \
3421
208k
      else nextOp ();                                         \
3422
208k
  }                                                           \
Unexecuted instantiation: m3_compile.c:op_i32_BranchIf_Equal_sr
Unexecuted instantiation: m3_compile.c:op_i32_BranchIf_NotEqual_sr
3423
  d_m3Op(TYPE##_BranchIf_##NAME##_ss)                         \
3424
2.99M
  {                                                           \
3425
2.99M
      TYPE operand2 = slot (TYPE);                            \
3426
2.99M
      TYPE operand1 = slot (TYPE);                            \
3427
2.99M
      pc_t branch   = immediate (pc_t);                       \
3428
2.99M
      if (operand1 OPER operand2)                             \
3429
2.99M
          jumpOp (branch);                                    \
3430
2.99M
      else nextOp ();                                         \
3431
2.99M
  }                                                           \
m3_compile.c:op_i32_BranchIf_Equal_ss
Line
Count
Source
3424
170k
  {                                                           \
3425
170k
      TYPE operand2 = slot (TYPE);                            \
3426
170k
      TYPE operand1 = slot (TYPE);                            \
3427
170k
      pc_t branch   = immediate (pc_t);                       \
3428
170k
      if (operand1 OPER operand2)                             \
3429
170k
          jumpOp (branch);                                    \
3430
170k
      else nextOp ();                                         \
3431
170k
  }                                                           \
m3_compile.c:op_i32_BranchIf_NotEqual_ss
Line
Count
Source
3424
179k
  {                                                           \
3425
179k
      TYPE operand2 = slot (TYPE);                            \
3426
179k
      TYPE operand1 = slot (TYPE);                            \
3427
179k
      pc_t branch   = immediate (pc_t);                       \
3428
179k
      if (operand1 OPER operand2)                             \
3429
179k
          jumpOp (branch);                                    \
3430
179k
      else nextOp ();                                         \
3431
179k
  }                                                           \
m3_compile.c:op_i32_BranchIf_LessThan_ss
Line
Count
Source
3424
163k
  {                                                           \
3425
163k
      TYPE operand2 = slot (TYPE);                            \
3426
163k
      TYPE operand1 = slot (TYPE);                            \
3427
163k
      pc_t branch   = immediate (pc_t);                       \
3428
163k
      if (operand1 OPER operand2)                             \
3429
163k
          jumpOp (branch);                                    \
3430
163k
      else nextOp ();                                         \
3431
163k
  }                                                           \
m3_compile.c:op_u32_BranchIf_LessThan_ss
Line
Count
Source
3424
291k
  {                                                           \
3425
291k
      TYPE operand2 = slot (TYPE);                            \
3426
291k
      TYPE operand1 = slot (TYPE);                            \
3427
291k
      pc_t branch   = immediate (pc_t);                       \
3428
291k
      if (operand1 OPER operand2)                             \
3429
291k
          jumpOp (branch);                                    \
3430
291k
      else nextOp ();                                         \
3431
291k
  }                                                           \
m3_compile.c:op_i32_BranchIf_GreaterThan_ss
Line
Count
Source
3424
292k
  {                                                           \
3425
292k
      TYPE operand2 = slot (TYPE);                            \
3426
292k
      TYPE operand1 = slot (TYPE);                            \
3427
292k
      pc_t branch   = immediate (pc_t);                       \
3428
292k
      if (operand1 OPER operand2)                             \
3429
292k
          jumpOp (branch);                                    \
3430
292k
      else nextOp ();                                         \
3431
292k
  }                                                           \
m3_compile.c:op_u32_BranchIf_GreaterThan_ss
Line
Count
Source
3424
306k
  {                                                           \
3425
306k
      TYPE operand2 = slot (TYPE);                            \
3426
306k
      TYPE operand1 = slot (TYPE);                            \
3427
306k
      pc_t branch   = immediate (pc_t);                       \
3428
306k
      if (operand1 OPER operand2)                             \
3429
306k
          jumpOp (branch);                                    \
3430
306k
      else nextOp ();                                         \
3431
306k
  }                                                           \
m3_compile.c:op_i32_BranchIf_LessThanOrEqual_ss
Line
Count
Source
3424
500k
  {                                                           \
3425
500k
      TYPE operand2 = slot (TYPE);                            \
3426
500k
      TYPE operand1 = slot (TYPE);                            \
3427
500k
      pc_t branch   = immediate (pc_t);                       \
3428
500k
      if (operand1 OPER operand2)                             \
3429
500k
          jumpOp (branch);                                    \
3430
500k
      else nextOp ();                                         \
3431
500k
  }                                                           \
m3_compile.c:op_u32_BranchIf_LessThanOrEqual_ss
Line
Count
Source
3424
390k
  {                                                           \
3425
390k
      TYPE operand2 = slot (TYPE);                            \
3426
390k
      TYPE operand1 = slot (TYPE);                            \
3427
390k
      pc_t branch   = immediate (pc_t);                       \
3428
390k
      if (operand1 OPER operand2)                             \
3429
390k
          jumpOp (branch);                                    \
3430
390k
      else nextOp ();                                         \
3431
390k
  }                                                           \
m3_compile.c:op_i32_BranchIf_GreaterThanOrEqual_ss
Line
Count
Source
3424
448k
  {                                                           \
3425
448k
      TYPE operand2 = slot (TYPE);                            \
3426
448k
      TYPE operand1 = slot (TYPE);                            \
3427
448k
      pc_t branch   = immediate (pc_t);                       \
3428
448k
      if (operand1 OPER operand2)                             \
3429
448k
          jumpOp (branch);                                    \
3430
448k
      else nextOp ();                                         \
3431
448k
  }                                                           \
m3_compile.c:op_u32_BranchIf_GreaterThanOrEqual_ss
Line
Count
Source
3424
252k
  {                                                           \
3425
252k
      TYPE operand2 = slot (TYPE);                            \
3426
252k
      TYPE operand1 = slot (TYPE);                            \
3427
252k
      pc_t branch   = immediate (pc_t);                       \
3428
252k
      if (operand1 OPER operand2)                             \
3429
252k
          jumpOp (branch);                                    \
3430
252k
      else nextOp ();                                         \
3431
252k
  }                                                           \
3432
  d_m3Op(TYPE##_If_##NAME##_rs)                               \
3433
13.0M
  {                                                           \
3434
13.0M
      TYPE operand = slot (TYPE);                             \
3435
13.0M
      pc_t elsePC  = immediate (pc_t);                        \
3436
13.0M
      if (operand OPER ((TYPE) _r0))                          \
3437
13.0M
          nextOp ();                                          \
3438
13.0M
      else jumpOp (elsePC);                                   \
3439
13.0M
  }                                                           \
m3_compile.c:op_i32_If_Equal_rs
Line
Count
Source
3433
1.82M
  {                                                           \
3434
1.82M
      TYPE operand = slot (TYPE);                             \
3435
1.82M
      pc_t elsePC  = immediate (pc_t);                        \
3436
1.82M
      if (operand OPER ((TYPE) _r0))                          \
3437
1.82M
          nextOp ();                                          \
3438
1.82M
      else jumpOp (elsePC);                                   \
3439
1.82M
  }                                                           \
m3_compile.c:op_i32_If_NotEqual_rs
Line
Count
Source
3433
1.75M
  {                                                           \
3434
1.75M
      TYPE operand = slot (TYPE);                             \
3435
1.75M
      pc_t elsePC  = immediate (pc_t);                        \
3436
1.75M
      if (operand OPER ((TYPE) _r0))                          \
3437
1.75M
          nextOp ();                                          \
3438
1.75M
      else jumpOp (elsePC);                                   \
3439
1.75M
  }                                                           \
m3_compile.c:op_i32_If_LessThan_rs
Line
Count
Source
3433
1.26M
  {                                                           \
3434
1.26M
      TYPE operand = slot (TYPE);                             \
3435
1.26M
      pc_t elsePC  = immediate (pc_t);                        \
3436
1.26M
      if (operand OPER ((TYPE) _r0))                          \
3437
1.26M
          nextOp ();                                          \
3438
1.26M
      else jumpOp (elsePC);                                   \
3439
1.26M
  }                                                           \
m3_compile.c:op_u32_If_LessThan_rs
Line
Count
Source
3433
1.66M
  {                                                           \
3434
1.66M
      TYPE operand = slot (TYPE);                             \
3435
1.66M
      pc_t elsePC  = immediate (pc_t);                        \
3436
1.66M
      if (operand OPER ((TYPE) _r0))                          \
3437
1.66M
          nextOp ();                                          \
3438
1.66M
      else jumpOp (elsePC);                                   \
3439
1.66M
  }                                                           \
m3_compile.c:op_i32_If_GreaterThan_rs
Line
Count
Source
3433
1.06M
  {                                                           \
3434
1.06M
      TYPE operand = slot (TYPE);                             \
3435
1.06M
      pc_t elsePC  = immediate (pc_t);                        \
3436
1.06M
      if (operand OPER ((TYPE) _r0))                          \
3437
1.06M
          nextOp ();                                          \
3438
1.06M
      else jumpOp (elsePC);                                   \
3439
1.06M
  }                                                           \
m3_compile.c:op_u32_If_GreaterThan_rs
Line
Count
Source
3433
1.14M
  {                                                           \
3434
1.14M
      TYPE operand = slot (TYPE);                             \
3435
1.14M
      pc_t elsePC  = immediate (pc_t);                        \
3436
1.14M
      if (operand OPER ((TYPE) _r0))                          \
3437
1.14M
          nextOp ();                                          \
3438
1.14M
      else jumpOp (elsePC);                                   \
3439
1.14M
  }                                                           \
m3_compile.c:op_i32_If_LessThanOrEqual_rs
Line
Count
Source
3433
1.47M
  {                                                           \
3434
1.47M
      TYPE operand = slot (TYPE);                             \
3435
1.47M
      pc_t elsePC  = immediate (pc_t);                        \
3436
1.47M
      if (operand OPER ((TYPE) _r0))                          \
3437
1.47M
          nextOp ();                                          \
3438
1.47M
      else jumpOp (elsePC);                                   \
3439
1.47M
  }                                                           \
m3_compile.c:op_u32_If_LessThanOrEqual_rs
Line
Count
Source
3433
977k
  {                                                           \
3434
977k
      TYPE operand = slot (TYPE);                             \
3435
977k
      pc_t elsePC  = immediate (pc_t);                        \
3436
977k
      if (operand OPER ((TYPE) _r0))                          \
3437
977k
          nextOp ();                                          \
3438
977k
      else jumpOp (elsePC);                                   \
3439
977k
  }                                                           \
m3_compile.c:op_i32_If_GreaterThanOrEqual_rs
Line
Count
Source
3433
1.00M
  {                                                           \
3434
1.00M
      TYPE operand = slot (TYPE);                             \
3435
1.00M
      pc_t elsePC  = immediate (pc_t);                        \
3436
1.00M
      if (operand OPER ((TYPE) _r0))                          \
3437
1.00M
          nextOp ();                                          \
3438
1.00M
      else jumpOp (elsePC);                                   \
3439
1.00M
  }                                                           \
m3_compile.c:op_u32_If_GreaterThanOrEqual_rs
Line
Count
Source
3433
855k
  {                                                           \
3434
855k
      TYPE operand = slot (TYPE);                             \
3435
855k
      pc_t elsePC  = immediate (pc_t);                        \
3436
855k
      if (operand OPER ((TYPE) _r0))                          \
3437
855k
          nextOp ();                                          \
3438
855k
      else jumpOp (elsePC);                                   \
3439
855k
  }                                                           \
3440
  d_m3Op(TYPE##_If_##NAME##_sr)                               \
3441
11.0M
  {                                                           \
3442
11.0M
      TYPE operand = slot (TYPE);                             \
3443
11.0M
      pc_t elsePC  = immediate (pc_t);                        \
3444
11.0M
      if (((TYPE) _r0) OPER operand)                          \
3445
11.0M
          nextOp ();                                          \
3446
11.0M
      else jumpOp (elsePC);                                   \
3447
11.0M
  }                                                           \
m3_compile.c:op_i32_If_LessThan_sr
Line
Count
Source
3441
984k
  {                                                           \
3442
984k
      TYPE operand = slot (TYPE);                             \
3443
984k
      pc_t elsePC  = immediate (pc_t);                        \
3444
984k
      if (((TYPE) _r0) OPER operand)                          \
3445
984k
          nextOp ();                                          \
3446
984k
      else jumpOp (elsePC);                                   \
3447
984k
  }                                                           \
m3_compile.c:op_u32_If_LessThan_sr
Line
Count
Source
3441
1.39M
  {                                                           \
3442
1.39M
      TYPE operand = slot (TYPE);                             \
3443
1.39M
      pc_t elsePC  = immediate (pc_t);                        \
3444
1.39M
      if (((TYPE) _r0) OPER operand)                          \
3445
1.39M
          nextOp ();                                          \
3446
1.39M
      else jumpOp (elsePC);                                   \
3447
1.39M
  }                                                           \
m3_compile.c:op_i32_If_GreaterThan_sr
Line
Count
Source
3441
1.67M
  {                                                           \
3442
1.67M
      TYPE operand = slot (TYPE);                             \
3443
1.67M
      pc_t elsePC  = immediate (pc_t);                        \
3444
1.67M
      if (((TYPE) _r0) OPER operand)                          \
3445
1.67M
          nextOp ();                                          \
3446
1.67M
      else jumpOp (elsePC);                                   \
3447
1.67M
  }                                                           \
m3_compile.c:op_u32_If_GreaterThan_sr
Line
Count
Source
3441
1.22M
  {                                                           \
3442
1.22M
      TYPE operand = slot (TYPE);                             \
3443
1.22M
      pc_t elsePC  = immediate (pc_t);                        \
3444
1.22M
      if (((TYPE) _r0) OPER operand)                          \
3445
1.22M
          nextOp ();                                          \
3446
1.22M
      else jumpOp (elsePC);                                   \
3447
1.22M
  }                                                           \
m3_compile.c:op_i32_If_LessThanOrEqual_sr
Line
Count
Source
3441
1.68M
  {                                                           \
3442
1.68M
      TYPE operand = slot (TYPE);                             \
3443
1.68M
      pc_t elsePC  = immediate (pc_t);                        \
3444
1.68M
      if (((TYPE) _r0) OPER operand)                          \
3445
1.68M
          nextOp ();                                          \
3446
1.68M
      else jumpOp (elsePC);                                   \
3447
1.68M
  }                                                           \
m3_compile.c:op_u32_If_LessThanOrEqual_sr
Line
Count
Source
3441
1.09M
  {                                                           \
3442
1.09M
      TYPE operand = slot (TYPE);                             \
3443
1.09M
      pc_t elsePC  = immediate (pc_t);                        \
3444
1.09M
      if (((TYPE) _r0) OPER operand)                          \
3445
1.09M
          nextOp ();                                          \
3446
1.09M
      else jumpOp (elsePC);                                   \
3447
1.09M
  }                                                           \
m3_compile.c:op_i32_If_GreaterThanOrEqual_sr
Line
Count
Source
3441
1.70M
  {                                                           \
3442
1.70M
      TYPE operand = slot (TYPE);                             \
3443
1.70M
      pc_t elsePC  = immediate (pc_t);                        \
3444
1.70M
      if (((TYPE) _r0) OPER operand)                          \
3445
1.70M
          nextOp ();                                          \
3446
1.70M
      else jumpOp (elsePC);                                   \
3447
1.70M
  }                                                           \
m3_compile.c:op_u32_If_GreaterThanOrEqual_sr
Line
Count
Source
3441
1.29M
  {                                                           \
3442
1.29M
      TYPE operand = slot (TYPE);                             \
3443
1.29M
      pc_t elsePC  = immediate (pc_t);                        \
3444
1.29M
      if (((TYPE) _r0) OPER operand)                          \
3445
1.29M
          nextOp ();                                          \
3446
1.29M
      else jumpOp (elsePC);                                   \
3447
1.29M
  }                                                           \
Unexecuted instantiation: m3_compile.c:op_i32_If_Equal_sr
Unexecuted instantiation: m3_compile.c:op_i32_If_NotEqual_sr
3448
  d_m3Op(TYPE##_If_##NAME##_ss)                               \
3449
9.03M
  {                                                           \
3450
9.03M
      TYPE operand2 = slot (TYPE);                            \
3451
9.03M
      TYPE operand1 = slot (TYPE);                            \
3452
9.03M
      pc_t elsePC   = immediate (pc_t);                       \
3453
9.03M
      if (operand1 OPER operand2)                             \
3454
9.03M
          nextOp ();                                          \
3455
9.03M
      else jumpOp (elsePC);                                   \
3456
9.03M
  }
m3_compile.c:op_i32_If_Equal_ss
Line
Count
Source
3449
630k
  {                                                           \
3450
630k
      TYPE operand2 = slot (TYPE);                            \
3451
630k
      TYPE operand1 = slot (TYPE);                            \
3452
630k
      pc_t elsePC   = immediate (pc_t);                       \
3453
630k
      if (operand1 OPER operand2)                             \
3454
630k
          nextOp ();                                          \
3455
630k
      else jumpOp (elsePC);                                   \
3456
630k
  }
m3_compile.c:op_i32_If_NotEqual_ss
Line
Count
Source
3449
1.09M
  {                                                           \
3450
1.09M
      TYPE operand2 = slot (TYPE);                            \
3451
1.09M
      TYPE operand1 = slot (TYPE);                            \
3452
1.09M
      pc_t elsePC   = immediate (pc_t);                       \
3453
1.09M
      if (operand1 OPER operand2)                             \
3454
1.09M
          nextOp ();                                          \
3455
1.09M
      else jumpOp (elsePC);                                   \
3456
1.09M
  }
m3_compile.c:op_i32_If_LessThan_ss
Line
Count
Source
3449
1.05M
  {                                                           \
3450
1.05M
      TYPE operand2 = slot (TYPE);                            \
3451
1.05M
      TYPE operand1 = slot (TYPE);                            \
3452
1.05M
      pc_t elsePC   = immediate (pc_t);                       \
3453
1.05M
      if (operand1 OPER operand2)                             \
3454
1.05M
          nextOp ();                                          \
3455
1.05M
      else jumpOp (elsePC);                                   \
3456
1.05M
  }
m3_compile.c:op_u32_If_LessThan_ss
Line
Count
Source
3449
1.17M
  {                                                           \
3450
1.17M
      TYPE operand2 = slot (TYPE);                            \
3451
1.17M
      TYPE operand1 = slot (TYPE);                            \
3452
1.17M
      pc_t elsePC   = immediate (pc_t);                       \
3453
1.17M
      if (operand1 OPER operand2)                             \
3454
1.17M
          nextOp ();                                          \
3455
1.17M
      else jumpOp (elsePC);                                   \
3456
1.17M
  }
m3_compile.c:op_i32_If_GreaterThan_ss
Line
Count
Source
3449
489k
  {                                                           \
3450
489k
      TYPE operand2 = slot (TYPE);                            \
3451
489k
      TYPE operand1 = slot (TYPE);                            \
3452
489k
      pc_t elsePC   = immediate (pc_t);                       \
3453
489k
      if (operand1 OPER operand2)                             \
3454
489k
          nextOp ();                                          \
3455
489k
      else jumpOp (elsePC);                                   \
3456
489k
  }
m3_compile.c:op_u32_If_GreaterThan_ss
Line
Count
Source
3449
1.27M
  {                                                           \
3450
1.27M
      TYPE operand2 = slot (TYPE);                            \
3451
1.27M
      TYPE operand1 = slot (TYPE);                            \
3452
1.27M
      pc_t elsePC   = immediate (pc_t);                       \
3453
1.27M
      if (operand1 OPER operand2)                             \
3454
1.27M
          nextOp ();                                          \
3455
1.27M
      else jumpOp (elsePC);                                   \
3456
1.27M
  }
m3_compile.c:op_i32_If_LessThanOrEqual_ss
Line
Count
Source
3449
496k
  {                                                           \
3450
496k
      TYPE operand2 = slot (TYPE);                            \
3451
496k
      TYPE operand1 = slot (TYPE);                            \
3452
496k
      pc_t elsePC   = immediate (pc_t);                       \
3453
496k
      if (operand1 OPER operand2)                             \
3454
496k
          nextOp ();                                          \
3455
496k
      else jumpOp (elsePC);                                   \
3456
496k
  }
m3_compile.c:op_u32_If_LessThanOrEqual_ss
Line
Count
Source
3449
1.32M
  {                                                           \
3450
1.32M
      TYPE operand2 = slot (TYPE);                            \
3451
1.32M
      TYPE operand1 = slot (TYPE);                            \
3452
1.32M
      pc_t elsePC   = immediate (pc_t);                       \
3453
1.32M
      if (operand1 OPER operand2)                             \
3454
1.32M
          nextOp ();                                          \
3455
1.32M
      else jumpOp (elsePC);                                   \
3456
1.32M
  }
m3_compile.c:op_i32_If_GreaterThanOrEqual_ss
Line
Count
Source
3449
967k
  {                                                           \
3450
967k
      TYPE operand2 = slot (TYPE);                            \
3451
967k
      TYPE operand1 = slot (TYPE);                            \
3452
967k
      pc_t elsePC   = immediate (pc_t);                       \
3453
967k
      if (operand1 OPER operand2)                             \
3454
967k
          nextOp ();                                          \
3455
967k
      else jumpOp (elsePC);                                   \
3456
967k
  }
m3_compile.c:op_u32_If_GreaterThanOrEqual_ss
Line
Count
Source
3449
516k
  {                                                           \
3450
516k
      TYPE operand2 = slot (TYPE);                            \
3451
516k
      TYPE operand1 = slot (TYPE);                            \
3452
516k
      pc_t elsePC   = immediate (pc_t);                       \
3453
516k
      if (operand1 OPER operand2)                             \
3454
516k
          nextOp ();                                          \
3455
516k
      else jumpOp (elsePC);                                   \
3456
516k
  }
3457
3458
d_m3FusedCmpBranch(i32, Equal, ==)
3459
d_m3FusedCmpBranch(i32, NotEqual, !=)
3460
d_m3FusedCmpBranch(i32, LessThan, <)
3461
d_m3FusedCmpBranch(i32, GreaterThan, >)
3462
d_m3FusedCmpBranch(i32, LessThanOrEqual, <=)
3463
d_m3FusedCmpBranch(i32, GreaterThanOrEqual, >=)
3464
d_m3FusedCmpBranch(u32, LessThan, <)
3465
d_m3FusedCmpBranch(u32, GreaterThan, >)
3466
d_m3FusedCmpBranch(u32, LessThanOrEqual, <=)
3467
d_m3FusedCmpBranch(u32, GreaterThanOrEqual, >=)
3468
3469
// i32.eqz is unary: form _r has the operand in _r0 (no operand immediate), _s reads a slot
3470
d_m3Op(i32_BranchIfEqz_r)
3471
109k
{
3472
109k
    pc_t branch = immediate(pc_t);
3473
109k
    if (((i32)_r0) == 0) {
3474
55.7k
        jumpOp(branch);
3475
55.7k
    } else {
3476
53.5k
        nextOp();
3477
53.5k
    }
3478
109k
}
3479
3480
d_m3Op(i32_BranchIfEqz_s)
3481
223k
{
3482
223k
    i32  operand = slot(i32);
3483
223k
    pc_t branch = immediate(pc_t);
3484
223k
    if (operand == 0) {
3485
43.3k
        jumpOp(branch);
3486
180k
    } else {
3487
180k
        nextOp();
3488
180k
    }
3489
223k
}
3490
3491
d_m3Op(i32_IfEqz_r)
3492
1.18M
{
3493
1.18M
    pc_t elsePC = immediate(pc_t);
3494
1.18M
    if (((i32)_r0) == 0) {
3495
516k
        nextOp();
3496
668k
    } else {
3497
668k
        jumpOp(elsePC);
3498
668k
    }
3499
1.18M
}
3500
3501
d_m3Op(i32_IfEqz_s)
3502
606k
{
3503
606k
    i32  operand = slot(i32);
3504
606k
    pc_t elsePC = immediate(pc_t);
3505
606k
    if (operand == 0) {
3506
273k
        nextOp();
3507
333k
    } else {
3508
333k
        jumpOp(elsePC);
3509
333k
    }
3510
606k
}
3511
3512
#endif // d_m3FuseBranch
3513
3514
3515
d_m3Op(BranchIfPrologue_r)
3516
641k
{
3517
641k
    i32  condition = (i32)_r0;
3518
641k
    pc_t branch = immediate(pc_t);
3519
3520
641k
    if (condition) {
3521
        // this is the "prologue" that ends with
3522
        // a plain branch to the actual target
3523
322k
        nextOp();
3524
322k
    } else {
3525
319k
        jumpOp(branch); // jump over the prologue
3526
319k
    }
3527
641k
}
3528
3529
3530
d_m3Op(BranchIfPrologue_s)
3531
277k
{
3532
277k
    i32  condition = slot(i32);
3533
277k
    pc_t branch = immediate(pc_t);
3534
3535
277k
    if (condition) {
3536
122k
        nextOp();
3537
155k
    } else {
3538
155k
        jumpOp(branch);
3539
155k
    }
3540
277k
}
3541
3542
3543
d_m3Op(ContinueLoop)
3544
2.57M
{
3545
2.57M
    m3StackCheck();
3546
3547
2.57M
    void* loopId = immediate(void*);
3548
2.57M
    return loopId;
3549
2.57M
}
3550
3551
3552
d_m3Op(ContinueLoopIf)
3553
2.39M
{
3554
2.39M
    i32   condition = (i32)_r0;
3555
2.39M
    void* loopId = immediate(void*);
3556
3557
2.39M
    if (condition) {
3558
2.07M
        return loopId;
3559
2.07M
    } else {
3560
316k
        nextOp();
3561
316k
    }
3562
2.39M
}
3563
3564
3565
#if d_m3HasStackSwitching
3566
3567
// This is where execution can "escape" the M3 code and callback to the client / fiber switch
3568
// OR it can go in the Loop operation. I think it's best to do here. adding code to the loop operation
3569
// has the potential to increase its native-stack usage.
3570
3571
d_m3Op(ContinueLoop_Suspendable)
3572
0
{
3573
0
    m3StackCheck();
3574
3575
0
    IM3Runtime runtime = m3MemRuntime(_mem);
3576
0
    if (M3_UNLIKELY(runtime->suspendRequested and runtime->activeContinuation)) {
3577
0
        SuspendWithoutTag(runtime, runtime->activeContinuation, safepoint_op, _pc - 1, _sp,
3578
0
                          d_m3ExpRegArgs(_r0, _fp0));
3579
3580
0
        return m3Err_continuationSuspended;
3581
0
    }
3582
3583
0
    void* loopId = immediate(void*);
3584
0
    return loopId;
3585
0
}
3586
3587
3588
#  if !d_m3EntryKeepsFrame
3589
// op_Entry, in code compiled while the runtime is suspendable: once the frame is
3590
// set up, it checks for a pause request. Recursion passes one of these on every
3591
// lap, as a loop passes its back edge, so a pause the host requests reaches code
3592
// that has no loop. A pause here stops at the body's first operation, so going
3593
// on from it is going on past the check.
3594
d_m3Op(Entry_Suspendable)
3595
0
{
3596
0
    d_m3ClearRegisters
3597
3598
0
    IM3Function function = immediate(IM3Function);
3599
3600
0
    if (EntryFits(function, _sp, _mem)) {
3601
0
        EnterFrame(function, _sp);
3602
3603
0
        IM3Runtime runtime = m3MemRuntime(_mem);
3604
0
        if (M3_UNLIKELY(runtime->suspendRequested and runtime->activeContinuation)) {
3605
0
            SuspendWithoutTag(runtime, runtime->activeContinuation, safepoint_entry, _pc, _sp,
3606
0
                              d_m3ExpRegArgs(_r0, _fp0));
3607
3608
0
            return m3Err_continuationSuspended;
3609
0
        }
3610
3611
0
        nextOpDirect();
3612
0
    } else {
3613
0
        newTrap(m3Err_trapStackOverflow);
3614
0
    }
3615
0
}
3616
#  endif
3617
3618
3619
// The check op_Entry_Suspendable makes, as an operation of its own for the
3620
// builds whose op_Entry keeps a frame and so cannot make it: the start of a
3621
// function's body, in code compiled while the runtime is suspendable
3622
d_m3Op(EntryCheck)
3623
0
{
3624
0
    IM3Runtime runtime = m3MemRuntime(_mem);
3625
0
    if (M3_UNLIKELY(runtime->suspendRequested and runtime->activeContinuation)) {
3626
0
        SuspendWithoutTag(runtime, runtime->activeContinuation, safepoint_entry, _pc - 1, _sp,
3627
0
                          d_m3ExpRegArgs(_r0, _fp0));
3628
3629
0
        return m3Err_continuationSuspended;
3630
0
    }
3631
3632
0
    nextOp();
3633
0
}
3634
3635
3636
d_m3Op(ContinueLoopIf_Suspendable)
3637
0
{
3638
0
    i32   condition = (i32)_r0;
3639
0
    void* loopId = immediate(void*);
3640
3641
0
    if (condition) {
3642
0
        IM3Runtime runtime = m3MemRuntime(_mem);
3643
0
        if (M3_UNLIKELY(runtime->suspendRequested and runtime->activeContinuation)) {
3644
0
            SuspendWithoutTag(runtime, runtime->activeContinuation, safepoint_op, _pc - 2, _sp,
3645
0
                              d_m3ExpRegArgs(_r0, _fp0));
3646
3647
0
            return m3Err_continuationSuspended;
3648
0
        }
3649
0
        return loopId;
3650
0
    } else {
3651
0
        nextOp();
3652
0
    }
3653
0
}
3654
3655
3656
// Carries a resumed back edge or function entry on past the check it paused in
3657
// (see M3Runtime.resumePastCheck), by running the operation the check stands
3658
// in front of: the plain back edge on the same immediates, or whatever follows
3659
// the entry check.
3660
static
3661
m3ret_t ResumePastCheck (IM3Continuation i_cont, M3MemoryHeader* _mem)
3662
0
{
3663
0
    pc_t         check = i_cont->pc;
3664
0
    IM3Operation op = (IM3Operation)(*check);
3665
0
    pc_t         _pc = check + 1;
3666
0
    m3stack_t    _sp = i_cont->sp;
3667
0
    m3reg_t      _r0 = i_cont->r0;
3668
0
#  if d_m3HasFloat
3669
0
    f64 _fp0 = i_cont->fp0;
3670
0
#  endif
3671
3672
0
    if (op == op_ContinueLoop_Suspendable) {
3673
0
        op = op_ContinueLoop;
3674
0
    } else if (op == op_ContinueLoopIf_Suspendable) {
3675
0
        op = op_ContinueLoopIf;
3676
0
    } else if (op == op_EntryCheck) {
3677
0
        return nextOpImpl();
3678
0
    } else {
3679
0
        return d_m3CallWithRegs(check, _sp, _mem, _r0, _fp0);
3680
0
    }
3681
3682
#  if (d_m3EnableOpProfiling || d_m3EnableOpTracing)
3683
    return op(_pc, d_m3OpArgs, d_m3BaseCstr);
3684
#  else
3685
0
    return op(_pc, d_m3OpArgs);
3686
0
#  endif
3687
0
}
3688
#endif // d_m3HasStackSwitching
3689
3690
3691
d_m3Op(Const32)
3692
2.13M
{
3693
2.13M
    u32 value = *(u32*)_pc++;
3694
2.13M
    slot(u32) = value;
3695
2.13M
    nextOp();
3696
2.13M
}
3697
3698
3699
d_m3Op(Const64)
3700
9.07M
{
3701
    // where a pointer is 32 bits the two lines are only 4-byte aligned
3702
9.07M
    u64 value;
3703
9.07M
    memcpy(&value, _pc, sizeof(value));
3704
9.07M
    _pc += (M3_SIZEOF_PTR == 4) ? 2 : 1;
3705
9.07M
    slot(u64) = value;
3706
9.07M
    nextOp();
3707
9.07M
}
3708
3709
d_m3Op(Unsupported)
3710
0
{
3711
0
    newTrap(m3Err_trapUnsupportedInstruction);
3712
0
}
3713
3714
d_m3Op(Unreachable)
3715
7.75k
{
3716
7.75k
    m3StackCheck();
3717
7.75k
    newTrap(m3Err_trapUnreachable);
3718
7.75k
}
3719
3720
3721
d_m3Op(End)
3722
0
{
3723
0
    m3StackCheck();
3724
0
    return m3Err_none;
3725
0
}
3726
3727
3728
d_m3Op(SetGlobal_s32)
3729
240k
{
3730
240k
    u32* global = immediate(u32*);
3731
240k
    *global = slot(u32);
3732
3733
240k
    nextOp();
3734
240k
}
3735
3736
3737
d_m3Op(SetGlobal_s64)
3738
66.9k
{
3739
66.9k
    u64* global = immediate(u64*);
3740
66.9k
    *global = slot(u64);
3741
3742
66.9k
    nextOp();
3743
66.9k
}
3744
3745
#if d_m3HasFloat
3746
d_m3Op(SetGlobal_f32)
3747
0
{
3748
0
    f32* global = immediate(f32*);
3749
0
    *global = (f32)_fp0;
3750
3751
0
    nextOp();
3752
0
}
3753
3754
3755
d_m3Op(SetGlobal_f64)
3756
0
{
3757
0
    f64* global = immediate(f64*);
3758
0
    *global = _fp0;
3759
3760
0
    nextOp();
3761
0
}
3762
#endif
3763
3764
3765
#if d_m3HasMemory64
3766
3767
// Checks a 64-bit address and folds the memarg offset into it, leaving the
3768
// effective address in a slot the access that follows reads as an ordinary
3769
// 32-bit one, with an offset of zero. That keeps one op between a 64-bit
3770
// memory and the whole load/store table, rather than a second copy of it.
3771
//
3772
// The spec computes the effective address as a u65 and traps if it is out of
3773
// range. Here the address is first held against d_m3AddressLimit and the
3774
// compiler has already refused to emit this for an offset above it, so their
3775
// sum is below 2^53 and no wider arithmetic is needed. An address that then
3776
// passes the bounds check is below the memory's length, which no allocator
3777
// lets past 32 bits, so the truncation below is exact.
3778
d_m3Op(CheckAddr64)
3779
4.38M
{
3780
4.38M
    u64  operand = slot(u64);
3781
4.38M
    u32* address = slot_ptr(u32);
3782
3783
4.38M
    u64  offset;
3784
4.38M
    memcpy(&offset, _pc, sizeof(offset));
3785
4.38M
    _pc += (M3_SIZEOF_PTR == 4) ? 2 : 1;
3786
3787
4.38M
    if (M3_LIKELY(operand < d_m3AddressLimit)) {
3788
4.38M
        u64 effective = operand + offset;
3789
3790
        // the access itself checks its own size against what is left
3791
4.38M
        if (M3_LIKELY(effective < _mem->length)) {
3792
4.38M
            *address = (u32)effective;
3793
4.38M
            nextOp();
3794
4.38M
        }
3795
4.38M
    }
3796
3797
4.38M
    d_outOfBounds;
3798
4.38M
}
3799
3800
#endif // d_m3HasMemory64
3801
3802
3803
// Under d_m3GuardedMemory there is nothing to check: every address one of these
3804
// operations can name lands inside the memory's reservation, and the part of it the
3805
// memory does not have is not committed, so the access faults and RunCodeChecked
3806
// turns that into the trap the spec asks for.
3807
#if d_m3SkipMemoryBoundsCheck || d_m3GuardedMemory
3808
19.1M
#  define m3MemCheck(x) true
3809
#else
3810
#  define m3MemCheck(x) M3_LIKELY(x)
3811
#endif
3812
3813
// memcpy here is to support non-aligned access on some platforms.
3814
3815
#define d_m3Load(REG,DEST_TYPE,SRC_TYPE)                \
3816
3.92M
d_m3Op(DEST_TYPE##_Load_##SRC_TYPE##_r)                 \
3817
3.92M
{                                                       \
3818
3.92M
    d_m3TracePrepare                                    \
3819
3.92M
    u32 offset = immediate (u32);                       \
3820
3.92M
    d_m3PreloadNext ();                                 \
3821
3.92M
    u64 operand = (u32) _r0;                            \
3822
3.92M
    operand += offset;                                  \
3823
3.92M
                                                        \
3824
3.92M
    if (m3MemCheck(                                     \
3825
3.92M
        operand + sizeof (SRC_TYPE) <= _mem->length     \
3826
3.92M
    )) {                                                \
3827
3.92M
        {                                               \
3828
3.92M
            u8* src8 = m3MemData(_mem) + operand;       \
3829
3.92M
            SRC_TYPE value;                             \
3830
3.92M
            memcpy(&value, src8, sizeof(value));        \
3831
3.92M
            M3_BSWAP_##SRC_TYPE(value);                 \
3832
3.92M
            REG = (DEST_TYPE)value;                     \
3833
3.92M
            d_m3TraceLoad(DEST_TYPE, operand, REG);     \
3834
3.92M
        }                                               \
3835
3.92M
        nextOpPreloaded ();                             \
3836
3.92M
    } else d_outOfBounds;                               \
3837
3.92M
}                                                       \
3838
6.18M
d_m3Op(DEST_TYPE##_Load_##SRC_TYPE##_s)                 \
3839
6.18M
{                                                       \
3840
6.18M
    d_m3TracePrepare                                    \
3841
6.18M
    u64 operand = slot (u32);                           \
3842
6.18M
    u32 offset = immediate (u32);                       \
3843
6.18M
    d_m3PreloadNext ();                                 \
3844
6.18M
    operand += offset;                                  \
3845
6.18M
                                                        \
3846
6.18M
    if (m3MemCheck(                                     \
3847
6.18M
        operand + sizeof (SRC_TYPE) <= _mem->length     \
3848
6.18M
    )) {                                                \
3849
6.18M
        {                                               \
3850
6.18M
            u8* src8 = m3MemData(_mem) + operand;       \
3851
6.18M
            SRC_TYPE value;                             \
3852
6.18M
            memcpy(&value, src8, sizeof(value));        \
3853
6.18M
            M3_BSWAP_##SRC_TYPE(value);                 \
3854
6.18M
            REG = (DEST_TYPE)value;                     \
3855
6.18M
            d_m3TraceLoad(DEST_TYPE, operand, REG);     \
3856
6.18M
        }                                               \
3857
6.18M
        nextOpPreloaded ();                             \
3858
6.18M
    } else d_outOfBounds;                               \
3859
6.18M
}
3860
3861
//  printf ("get: %d -> %d\n", operand + offset, (i64) REG);
3862
3863
3864
#define d_m3Load_i(DEST_TYPE, SRC_TYPE) d_m3Load(_r0, DEST_TYPE, SRC_TYPE)
3865
#define d_m3Load_f(DEST_TYPE, SRC_TYPE) d_m3Load(_fp0, DEST_TYPE, SRC_TYPE)
3866
3867
#if d_m3HasFloat
3868
662k
d_m3Load_f(f32, f32);
m3_compile.c:op_f32_Load_f32_r
Line
Count
Source
3868
d_m3Load_f(f32, f32);
m3_compile.c:op_f32_Load_f32_s
Line
Count
Source
3868
d_m3Load_f(f32, f32);
3869
662k
d_m3Load_f(f64, f64);
m3_compile.c:op_f64_Load_f64_r
Line
Count
Source
3869
d_m3Load_f(f64, f64);
m3_compile.c:op_f64_Load_f64_s
Line
Count
Source
3869
d_m3Load_f(f64, f64);
3870
480k
#endif
3871
480k
3872
882k
d_m3Load_i(i32, i8);
m3_compile.c:op_i32_Load_i8_r
Line
Count
Source
3872
d_m3Load_i(i32, i8);
m3_compile.c:op_i32_Load_i8_s
Line
Count
Source
3872
d_m3Load_i(i32, i8);
3873
882k
d_m3Load_i(i32, u8);
m3_compile.c:op_i32_Load_u8_r
Line
Count
Source
3873
d_m3Load_i(i32, u8);
m3_compile.c:op_i32_Load_u8_s
Line
Count
Source
3873
d_m3Load_i(i32, u8);
3874
877k
d_m3Load_i(i32, i16);
m3_compile.c:op_i32_Load_i16_r
Line
Count
Source
3874
d_m3Load_i(i32, i16);
m3_compile.c:op_i32_Load_i16_s
Line
Count
Source
3874
d_m3Load_i(i32, i16);
3875
877k
d_m3Load_i(i32, u16);
m3_compile.c:op_i32_Load_u16_r
Line
Count
Source
3875
d_m3Load_i(i32, u16);
m3_compile.c:op_i32_Load_u16_s
Line
Count
Source
3875
d_m3Load_i(i32, u16);
3876
856k
d_m3Load_i(i32, i32);
m3_compile.c:op_i32_Load_i32_r
Line
Count
Source
3876
d_m3Load_i(i32, i32);
m3_compile.c:op_i32_Load_i32_s
Line
Count
Source
3876
d_m3Load_i(i32, i32);
3877
521k
3878
804k
d_m3Load_i(i64, i8);
m3_compile.c:op_i64_Load_i8_r
Line
Count
Source
3878
d_m3Load_i(i64, i8);
m3_compile.c:op_i64_Load_i8_s
Line
Count
Source
3878
d_m3Load_i(i64, i8);
3879
804k
d_m3Load_i(i64, u8);
m3_compile.c:op_i64_Load_u8_r
Line
Count
Source
3879
d_m3Load_i(i64, u8);
m3_compile.c:op_i64_Load_u8_s
Line
Count
Source
3879
d_m3Load_i(i64, u8);
3880
901k
d_m3Load_i(i64, i16);
m3_compile.c:op_i64_Load_i16_r
Line
Count
Source
3880
d_m3Load_i(i64, i16);
m3_compile.c:op_i64_Load_i16_s
Line
Count
Source
3880
d_m3Load_i(i64, i16);
3881
901k
d_m3Load_i(i64, u16);
m3_compile.c:op_i64_Load_u16_r
Line
Count
Source
3881
d_m3Load_i(i64, u16);
m3_compile.c:op_i64_Load_u16_s
Line
Count
Source
3881
d_m3Load_i(i64, u16);
3882
634k
d_m3Load_i(i64, i32);
m3_compile.c:op_i64_Load_i32_r
Line
Count
Source
3882
d_m3Load_i(i64, i32);
m3_compile.c:op_i64_Load_i32_s
Line
Count
Source
3882
d_m3Load_i(i64, i32);
3883
821k
d_m3Load_i(i64, u32);
m3_compile.c:op_i64_Load_u32_r
Line
Count
Source
3883
d_m3Load_i(i64, u32);
m3_compile.c:op_i64_Load_u32_s
Line
Count
Source
3883
d_m3Load_i(i64, u32);
3884
839k
d_m3Load_i(i64, i64);
m3_compile.c:op_i64_Load_i64_r
Line
Count
Source
3884
d_m3Load_i(i64, i64);
m3_compile.c:op_i64_Load_i64_s
Line
Count
Source
3884
d_m3Load_i(i64, i64);
3885
839k
3886
839k
#if d_m3FoldSetLocal
3887
839k
3888
839k
// destination-folded loads: the value goes to a trailing destination slot instead of _r0.
3889
839k
// operand immediates keep d_m3Load's order; the destination slot is the last immediate
3890
839k
#  define d_m3LoadFold(REG, DEST_TYPE, SRC_TYPE)          \
3891
839k
  d_m3Op(DEST_TYPE##_Load_##SRC_TYPE##_r_f)               \
3892
1.73M
  {                                                       \
3893
1.73M
      d_m3TracePrepare                                    \
3894
1.73M
      u32 offset = immediate (u32);                       \
3895
1.73M
      DEST_TYPE * dest = slot_ptr (DEST_TYPE);            \
3896
1.73M
      d_m3PreloadNext ();                                 \
3897
1.73M
      u64 operand = (u32) _r0;                            \
3898
1.73M
      operand += offset;                                  \
3899
1.73M
                                                          \
3900
1.73M
      if (m3MemCheck(                                     \
3901
1.73M
          operand + sizeof (SRC_TYPE) <= _mem->length     \
3902
1.73M
      )) {                                                \
3903
1.73M
          u8* src8 = m3MemData(_mem) + operand;           \
3904
1.73M
          SRC_TYPE value;                                 \
3905
1.73M
          memcpy(&value, src8, sizeof(value));            \
3906
1.73M
          M3_BSWAP_##SRC_TYPE(value);                     \
3907
1.73M
          DEST_TYPE result = (DEST_TYPE)value;            \
3908
1.73M
          * dest = result;  REG = result;                 \
3909
1.73M
          d_m3TraceLoad(DEST_TYPE, operand, result);      \
3910
1.73M
          nextOpPreloaded ();                             \
3911
1.73M
      } else d_outOfBounds;                               \
3912
1.73M
  }                                                       \
3913
  d_m3Op(DEST_TYPE##_Load_##SRC_TYPE##_s_f)               \
3914
2.61M
  {                                                       \
3915
2.61M
      d_m3TracePrepare                                    \
3916
2.61M
      u64 operand = slot (u32);                           \
3917
2.61M
      u32 offset = immediate (u32);                       \
3918
2.61M
      DEST_TYPE * dest = slot_ptr (DEST_TYPE);            \
3919
2.61M
      d_m3PreloadNext ();                                 \
3920
2.61M
      operand += offset;                                  \
3921
2.61M
                                                          \
3922
2.61M
      if (m3MemCheck(                                     \
3923
2.61M
          operand + sizeof (SRC_TYPE) <= _mem->length     \
3924
2.61M
      )) {                                                \
3925
2.61M
          u8* src8 = m3MemData(_mem) + operand;           \
3926
2.61M
          SRC_TYPE value;                                 \
3927
2.61M
          memcpy(&value, src8, sizeof(value));            \
3928
2.61M
          M3_BSWAP_##SRC_TYPE(value);                     \
3929
2.61M
          DEST_TYPE result = (DEST_TYPE)value;            \
3930
2.61M
          * dest = result;  REG = result;                 \
3931
2.61M
          d_m3TraceLoad(DEST_TYPE, operand, result);      \
3932
2.61M
          nextOpPreloaded ();                             \
3933
2.61M
      } else d_outOfBounds;                               \
3934
2.61M
  }
3935
3936
473k
d_m3LoadFold(_r0, i32, i8)
m3_compile.c:op_i32_Load_i8_r_f
Line
Count
Source
3936
d_m3LoadFold(_r0, i32, i8)
m3_compile.c:op_i32_Load_i8_s_f
Line
Count
Source
3936
d_m3LoadFold(_r0, i32, i8)
3937
347k
d_m3LoadFold(_r0, i32, u8)
m3_compile.c:op_i32_Load_u8_r_f
Line
Count
Source
3937
d_m3LoadFold(_r0, i32, u8)
m3_compile.c:op_i32_Load_u8_s_f
Line
Count
Source
3937
d_m3LoadFold(_r0, i32, u8)
3938
338k
d_m3LoadFold(_r0, i32, i16)
m3_compile.c:op_i32_Load_i16_r_f
Line
Count
Source
3938
d_m3LoadFold(_r0, i32, i16)
m3_compile.c:op_i32_Load_i16_s_f
Line
Count
Source
3938
d_m3LoadFold(_r0, i32, i16)
3939
352k
d_m3LoadFold(_r0, i32, u16)
m3_compile.c:op_i32_Load_u16_r_f
Line
Count
Source
3939
d_m3LoadFold(_r0, i32, u16)
m3_compile.c:op_i32_Load_u16_s_f
Line
Count
Source
3939
d_m3LoadFold(_r0, i32, u16)
3940
254k
d_m3LoadFold(_r0, i32, i32)
m3_compile.c:op_i32_Load_i32_r_f
Line
Count
Source
3940
d_m3LoadFold(_r0, i32, i32)
m3_compile.c:op_i32_Load_i32_s_f
Line
Count
Source
3940
d_m3LoadFold(_r0, i32, i32)
3941
3942
// The fold forms take the address from _r0 and write the result straight to the
3943
// destination slot, so they never touch _fp0 and the float widths need no register form.
3944
314k
d_m3LoadFold(_r0, i64, i8)
m3_compile.c:op_i64_Load_i8_r_f
Line
Count
Source
3944
d_m3LoadFold(_r0, i64, i8)
m3_compile.c:op_i64_Load_i8_s_f
Line
Count
Source
3944
d_m3LoadFold(_r0, i64, i8)
3945
270k
d_m3LoadFold(_r0, i64, u8)
m3_compile.c:op_i64_Load_u8_r_f
Line
Count
Source
3945
d_m3LoadFold(_r0, i64, u8)
m3_compile.c:op_i64_Load_u8_s_f
Line
Count
Source
3945
d_m3LoadFold(_r0, i64, u8)
3946
421k
d_m3LoadFold(_r0, i64, i16)
m3_compile.c:op_i64_Load_i16_r_f
Line
Count
Source
3946
d_m3LoadFold(_r0, i64, i16)
m3_compile.c:op_i64_Load_i16_s_f
Line
Count
Source
3946
d_m3LoadFold(_r0, i64, i16)
3947
282k
d_m3LoadFold(_r0, i64, u16)
m3_compile.c:op_i64_Load_u16_r_f
Line
Count
Source
3947
d_m3LoadFold(_r0, i64, u16)
m3_compile.c:op_i64_Load_u16_s_f
Line
Count
Source
3947
d_m3LoadFold(_r0, i64, u16)
3948
450k
d_m3LoadFold(_r0, i64, i32)
m3_compile.c:op_i64_Load_i32_r_f
Line
Count
Source
3948
d_m3LoadFold(_r0, i64, i32)
m3_compile.c:op_i64_Load_i32_s_f
Line
Count
Source
3948
d_m3LoadFold(_r0, i64, i32)
3949
322k
d_m3LoadFold(_r0, i64, u32)
m3_compile.c:op_i64_Load_u32_r_f
Line
Count
Source
3949
d_m3LoadFold(_r0, i64, u32)
m3_compile.c:op_i64_Load_u32_s_f
Line
Count
Source
3949
d_m3LoadFold(_r0, i64, u32)
3950
202k
d_m3LoadFold(_r0, i64, i64)
m3_compile.c:op_i64_Load_i64_r_f
Line
Count
Source
3950
d_m3LoadFold(_r0, i64, i64)
m3_compile.c:op_i64_Load_i64_s_f
Line
Count
Source
3950
d_m3LoadFold(_r0, i64, i64)
3951
#  if d_m3HasFloat
3952
209k
d_m3LoadFold(_fp0, f32, f32)
m3_compile.c:op_f32_Load_f32_r_f
Line
Count
Source
3952
d_m3LoadFold(_fp0, f32, f32)
m3_compile.c:op_f32_Load_f32_s_f
Line
Count
Source
3952
d_m3LoadFold(_fp0, f32, f32)
3953
101k
d_m3LoadFold(_fp0, f64, f64)
m3_compile.c:op_f64_Load_f64_r_f
Line
Count
Source
3953
d_m3LoadFold(_fp0, f64, f64)
m3_compile.c:op_f64_Load_f64_s_f
Line
Count
Source
3953
d_m3LoadFold(_fp0, f64, f64)
3954
#  endif
3955
3956
#endif // d_m3FoldSetLocal
3957
3958
#define d_m3Store(REG, SRC_TYPE, DEST_TYPE)             \
3959
1.31M
d_m3Op  (SRC_TYPE##_Store_##DEST_TYPE##_rs)             \
3960
1.31M
{                                                       \
3961
1.31M
    d_m3TracePrepare                                    \
3962
1.31M
    u64 operand = slot (u32);                           \
3963
1.31M
    u32 offset = immediate (u32);                       \
3964
1.31M
    d_m3PreloadNext ();                                 \
3965
1.31M
    operand += offset;                                  \
3966
1.31M
                                                        \
3967
1.31M
    if (m3MemCheck(                                     \
3968
1.31M
        operand + sizeof (DEST_TYPE) <= _mem->length    \
3969
1.31M
    )) {                                                \
3970
1.31M
        {                                               \
3971
1.31M
            d_m3TraceStore(SRC_TYPE, operand, REG);     \
3972
1.31M
            u8* mem8 = m3MemData(_mem) + operand;       \
3973
1.31M
            DEST_TYPE val = (DEST_TYPE) REG;            \
3974
1.31M
            M3_BSWAP_##DEST_TYPE(val);                  \
3975
1.31M
            memcpy(mem8, &val, sizeof(val));            \
3976
1.31M
        }                                               \
3977
1.31M
        nextOpPreloaded ();                             \
3978
1.31M
    } else d_outOfBounds;                               \
3979
1.31M
}                                                       \
3980
978k
d_m3Op  (SRC_TYPE##_Store_##DEST_TYPE##_sr)             \
3981
978k
{                                                       \
3982
978k
    d_m3TracePrepare                                    \
3983
978k
    const SRC_TYPE value = slot (SRC_TYPE);             \
3984
978k
    u64 operand = (u32) _r0;                            \
3985
978k
    u32 offset = immediate (u32);                       \
3986
978k
    d_m3PreloadNext ();                                 \
3987
978k
    operand += offset;                                  \
3988
978k
                                                        \
3989
978k
    if (m3MemCheck(                                     \
3990
978k
        operand + sizeof (DEST_TYPE) <= _mem->length    \
3991
978k
    )) {                                                \
3992
978k
        {                                               \
3993
978k
            d_m3TraceStore(SRC_TYPE, operand, value);   \
3994
978k
            u8* mem8 = m3MemData(_mem) + operand;       \
3995
978k
            DEST_TYPE val = (DEST_TYPE) value;          \
3996
978k
            M3_BSWAP_##DEST_TYPE(val);                  \
3997
978k
            memcpy(mem8, &val, sizeof(val));            \
3998
978k
        }                                               \
3999
978k
        nextOpPreloaded ();                             \
4000
978k
    } else d_outOfBounds;                               \
4001
978k
}                                                       \
4002
856k
d_m3Op  (SRC_TYPE##_Store_##DEST_TYPE##_ss)             \
4003
856k
{                                                       \
4004
856k
    d_m3TracePrepare                                    \
4005
856k
    const SRC_TYPE value = slot (SRC_TYPE);             \
4006
856k
    u64 operand = slot (u32);                           \
4007
856k
    u32 offset = immediate (u32);                       \
4008
856k
    d_m3PreloadNext ();                                 \
4009
856k
    operand += offset;                                  \
4010
856k
                                                        \
4011
856k
    if (m3MemCheck(                                     \
4012
856k
        operand + sizeof (DEST_TYPE) <= _mem->length    \
4013
856k
    )) {                                                \
4014
856k
        {                                               \
4015
856k
            d_m3TraceStore(SRC_TYPE, operand, value);   \
4016
856k
            u8* mem8 = m3MemData(_mem) + operand;       \
4017
856k
            DEST_TYPE val = (DEST_TYPE) value;          \
4018
856k
            M3_BSWAP_##DEST_TYPE(val);                  \
4019
856k
            memcpy(mem8, &val, sizeof(val));            \
4020
856k
        }                                               \
4021
856k
        nextOpPreloaded ();                             \
4022
856k
    } else d_outOfBounds;                               \
4023
856k
}
4024
4025
// both operands can be in regs when storing a float
4026
#define d_m3StoreFp(REG, TYPE)                          \
4027
68.9k
d_m3Op  (TYPE##_Store_##TYPE##_rr)                      \
4028
68.9k
{                                                       \
4029
68.9k
    d_m3TracePrepare                                    \
4030
68.9k
    u64 operand = (u32) _r0;                            \
4031
68.9k
    u32 offset = immediate (u32);                       \
4032
68.9k
    d_m3PreloadNext ();                                 \
4033
68.9k
    operand += offset;                                  \
4034
68.9k
                                                        \
4035
68.9k
    if (m3MemCheck(                                     \
4036
68.9k
        operand + sizeof (TYPE) <= _mem->length         \
4037
68.9k
    )) {                                                \
4038
68.9k
        {                                               \
4039
68.9k
            d_m3TraceStore(TYPE, operand, REG);         \
4040
68.9k
            u8* mem8 = m3MemData(_mem) + operand;       \
4041
68.9k
            TYPE val = (TYPE) REG;                      \
4042
68.9k
            M3_BSWAP_##TYPE(val);                       \
4043
68.9k
            memcpy(mem8, &val, sizeof(val));            \
4044
68.9k
        }                                               \
4045
68.9k
        nextOpPreloaded ();                             \
4046
68.9k
    } else d_outOfBounds;                               \
4047
68.9k
}
4048
4049
4050
#define d_m3Store_i(SRC_TYPE, DEST_TYPE) d_m3Store(_r0, SRC_TYPE, DEST_TYPE)
4051
#define d_m3Store_f(SRC_TYPE, DEST_TYPE) d_m3Store(_fp0, SRC_TYPE, DEST_TYPE) d_m3StoreFp (_fp0, SRC_TYPE);
4052
4053
#if d_m3HasFloat
4054
385k
d_m3Store_f(f32, f32)
m3_compile.c:op_f32_Store_f32_rs
Line
Count
Source
4054
d_m3Store_f(f32, f32)
m3_compile.c:op_f32_Store_f32_sr
Line
Count
Source
4054
d_m3Store_f(f32, f32)
m3_compile.c:op_f32_Store_f32_ss
Line
Count
Source
4054
d_m3Store_f(f32, f32)
m3_compile.c:op_f32_Store_f32_rr
Line
Count
Source
4054
d_m3Store_f(f32, f32)
4055
385k
d_m3Store_f(f64, f64)
m3_compile.c:op_f64_Store_f64_rs
Line
Count
Source
4055
d_m3Store_f(f64, f64)
m3_compile.c:op_f64_Store_f64_sr
Line
Count
Source
4055
d_m3Store_f(f64, f64)
m3_compile.c:op_f64_Store_f64_ss
Line
Count
Source
4055
d_m3Store_f(f64, f64)
m3_compile.c:op_f64_Store_f64_rr
Line
Count
Source
4055
d_m3Store_f(f64, f64)
4056
219k
#endif
4057
219k
4058
325k
d_m3Store_i(i32, u8)
m3_compile.c:op_i32_Store_u8_rs
Line
Count
Source
4058
d_m3Store_i(i32, u8)
m3_compile.c:op_i32_Store_u8_sr
Line
Count
Source
4058
d_m3Store_i(i32, u8)
m3_compile.c:op_i32_Store_u8_ss
Line
Count
Source
4058
d_m3Store_i(i32, u8)
4059
424k
d_m3Store_i(i32, i16)
m3_compile.c:op_i32_Store_i16_rs
Line
Count
Source
4059
d_m3Store_i(i32, i16)
m3_compile.c:op_i32_Store_i16_sr
Line
Count
Source
4059
d_m3Store_i(i32, i16)
m3_compile.c:op_i32_Store_i16_ss
Line
Count
Source
4059
d_m3Store_i(i32, i16)
4060
733k
d_m3Store_i(i32, i32)
m3_compile.c:op_i32_Store_i32_rs
Line
Count
Source
4060
d_m3Store_i(i32, i32)
m3_compile.c:op_i32_Store_i32_sr
Line
Count
Source
4060
d_m3Store_i(i32, i32)
m3_compile.c:op_i32_Store_i32_ss
Line
Count
Source
4060
d_m3Store_i(i32, i32)
4061
733k
4062
733k
d_m3Store_i(i64, u8)
m3_compile.c:op_i64_Store_u8_rs
Line
Count
Source
4062
d_m3Store_i(i64, u8)
m3_compile.c:op_i64_Store_u8_sr
Line
Count
Source
4062
d_m3Store_i(i64, u8)
m3_compile.c:op_i64_Store_u8_ss
Line
Count
Source
4062
d_m3Store_i(i64, u8)
4063
309k
d_m3Store_i(i64, i16)
m3_compile.c:op_i64_Store_i16_rs
Line
Count
Source
4063
d_m3Store_i(i64, i16)
m3_compile.c:op_i64_Store_i16_sr
Line
Count
Source
4063
d_m3Store_i(i64, i16)
m3_compile.c:op_i64_Store_i16_ss
Line
Count
Source
4063
d_m3Store_i(i64, i16)
4064
253k
d_m3Store_i(i64, i32)
m3_compile.c:op_i64_Store_i32_rs
Line
Count
Source
4064
d_m3Store_i(i64, i32)
m3_compile.c:op_i64_Store_i32_sr
Line
Count
Source
4064
d_m3Store_i(i64, i32)
m3_compile.c:op_i64_Store_i32_ss
Line
Count
Source
4064
d_m3Store_i(i64, i32)
4065
d_m3Store_i(i64, i64)
m3_compile.c:op_i64_Store_i64_rs
Line
Count
Source
4065
d_m3Store_i(i64, i64)
m3_compile.c:op_i64_Store_i64_sr
Line
Count
Source
4065
d_m3Store_i(i64, i64)
m3_compile.c:op_i64_Store_i64_ss
Line
Count
Source
4065
d_m3Store_i(i64, i64)
4066
4067
#include "m3_exec_atomic.h"
4068
4069
#undef m3MemCheck
4070
4071
4072
//---------------------------------------------------------------------------------------------------------------------
4073
// debug/profiling
4074
//---------------------------------------------------------------------------------------------------------------------
4075
#if d_m3EnableOpTracing
4076
d_m3RetSig debugOp (d_m3OpSig, cstr_t i_opcode)
4077
{
4078
    char name[100];
4079
    strcpy(name, strstr(i_opcode, "op_") + 3);
4080
    char* bracket = strstr(name, "(");
4081
    if (bracket) {
4082
        *bracket = 0;
4083
    }
4084
4085
    puts(name);
4086
    nextOpDirect();
4087
}
4088
#endif
4089
4090
#if d_m3EnableOpProfiling
4091
d_m3RetSig profileOp (d_m3OpSig, cstr_t i_operationName)
4092
{
4093
    ProfileHit(i_operationName);
4094
4095
    nextOpDirect();
4096
}
4097
4098
// Same, for an operation leaving by a branch: jumpOp hands the target pc in as _pc,
4099
// so dispatching from here lands exactly where jumpOpDirect would have.
4100
d_m3RetSig profileJumpOp (d_m3OpSig, cstr_t i_operationName)
4101
{
4102
    ProfileHit(i_operationName);
4103
4104
    nextOpDirect();
4105
}
4106
#endif
4107
4108
d_m3EndExternC
4109
4110
#endif // m3_exec_h