4 #include "opcode_helpers.h"
5 #include "x86_macros.h"
7 int OpAdvTable[OP_NUM_OPCODES];
9 jitoffs_t Write_Execute_Function(JitWriter *jit)
12 * The variables we're passed in:
13 * sp_context_t *ctx, uint32_t code_idx, cell_t *result
18 * Currently, we do not accept ctx->frm as the new frame pointer.
19 * Instead, we copy the frame from the stack pointer.
20 * This is because we do not support resuming or sleeping!
23 //:TODO: FIX THIS FOR THE EBP AND EDI SWITCHING
26 IA32_Push_Reg(jit, REG_EBP);
27 IA32_Mov_Reg_Rm(jit, REG_EBP, REG_ESP, MOD_REG);
32 IA32_Push_Reg(jit, REG_ESI);
33 IA32_Push_Reg(jit, REG_EDI);
34 IA32_Push_Reg(jit, REG_EBX);
36 //sub esp, 4*6 - allocate info array
37 //mov esi, esp - save info pointer
38 IA32_Sub_Rm_Imm8(jit, REG_ESP, 4*6, MOD_REG);
39 IA32_Mov_Reg_Rm(jit, AMX_REG_INFO, REG_ESP, MOD_REG);
41 /* Initial memory setup */
42 //mov eax, [ebp+16] - get result pointer
43 //mov [esi+8], eax - store into info pointer
44 //mov eax, [ebp+8] - get context
45 //mov [esi+12], eax - store context into info pointer
46 //mov ecx, [eax+<offs>] - get heap pointer
47 //mov [esi+4], ecx - store heap into info pointer
48 //mov edi, [eax+<offs>] - get data pointer
49 IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 16);
50 IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_RETVAL);
51 IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 8);
52 IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_CONTEXT);
53 IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, hp));
54 IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_HEAP);
55 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_DAT, REG_EAX, offsetof(sp_context_t, data));
58 //mov ebp, [eax+<offs>] - get stack pointer
59 //add ebp, edi - relocate to data section
60 //mov ebx, ebp - copy sp to frm
61 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_STK, REG_EAX, offsetof(sp_context_t, sp));
62 IA32_Add_Rm_Reg(jit, REG_EBP, AMX_REG_STK, AMX_REG_DAT);
63 IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_REG);
65 /* Info memory setup */
66 //mov ecx, edi - copy base of data to temp var
67 //add ecx, [eax+<offs>] - add memsize to get stack top
68 //mov [esi+16], ecx - store stack top into info pointer
69 //mov ecx, [eax+<offs>] - get heap low
70 //mov [esi+20], ecx - store heap low into info pointer
71 IA32_Mov_Reg_Rm(jit, REG_ECX, AMX_REG_DAT, MOD_REG);
72 IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, memory));
73 IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP);
74 IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, heapbase));
75 IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_HEAPLOW);
77 /* Remaining needed vars */
78 //mov ecx, [ebp+12] - get code index
79 //add ecx, [eax+<offs>] - add code base to index
80 //mov edx, [eax+<offs>] - get alt
81 //mov eax, [eax+<offs>] - get pri
82 IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EBP, 12);
83 IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, codebase));
84 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, REG_EAX, offsetof(sp_context_t, alt));
85 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, REG_EAX, offsetof(sp_context_t, pri));
87 /* by now, everything is set up, so we can call into the plugin */
89 IA32_Call_Reg(jit, REG_ECX);
91 /* if the code flow gets to here, there was a normal return */
92 //mov ebp, [esi+8] - get retval pointer
93 //mov [ebp], eax - store retval from PRI
94 //mov eax, SP_ERR_NONE - set no error
95 IA32_Mov_Reg_Rm_Disp8(jit, REG_EBP, AMX_REG_INFO, AMX_INFO_RETVAL);
96 IA32_Mov_Rm_Reg(jit, REG_EBP, AMX_REG_PRI, MOD_MEM_REG);
97 IA32_Mov_Reg_Imm32(jit, REG_EAX, SP_ERR_NONE);
99 /* save where error checking/halting functions should go to */
100 jitoffs_t offs_return;
101 CompData *data = (CompData *)jit->data;
102 if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
104 /* We have to write code assume we're breaking out of a call */
105 //jmp [past the next instruction]
107 jitoffs_t offs = IA32_Jump_Imm8(jit, 0);
108 offs_return = jit->jit_curpos();
109 IA32_Sub_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
110 IA32_Send_Jump8_Here(jit, offs);
112 offs_return = jit->jit_curpos();
116 * We are _not_ going to restore anything that was on the stack.
117 * This is a tiny, useless optimization based on the fact that
118 * BaseContext::Execute() automatically restores our values anyway.
127 IA32_Add_Rm_Imm8(jit, REG_ESP, 4*6, MOD_REG);
128 IA32_Pop_Reg(jit, REG_EBX);
129 IA32_Pop_Reg(jit, REG_EDI);
130 IA32_Pop_Reg(jit, REG_ESI);
131 IA32_Pop_Reg(jit, REG_EBP);
137 void Write_BreakDebug(JitWriter *jit)
141 //cmp [ecx+dbreak], 0
143 IA32_Push_Reg(jit, AMX_REG_TMP);
144 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
145 IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, dbreak), 0);
146 jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_NZ, 0);
153 //mov ecx, [ecx+dbreak]
157 IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_FRAME); //:TODO: move to regs and push? and dont disp for 0
158 IA32_Push_Rm_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, context));
159 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_TMP, offsetof(sp_context_t, dbreak));
160 IA32_Call_Reg(jit, AMX_REG_TMP);
161 IA32_Add_Rm_Imm8(jit, REG_ESP, 4*2, MOD_REG);
165 IA32_Send_Jump8_Here(jit, jmp);
166 IA32_Add_Rm_Imm8(jit, REG_ESP, 4*1, MOD_REG);
170 void Write_Error(JitWriter *jit, int error)
172 CompData *data = (CompData *)jit->data;
174 /* These are so small that we always inline them! */
176 //jmp [...jit_return]
177 IA32_Mov_Reg_Imm32(jit, REG_EAX, error);
178 jitoffs_t jmp = IA32_Jump_Imm32(jit, 0);
179 IA32_Write_Jump32(jit, jmp, data->jit_return);
182 void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg)
186 //divzero: (write error)
187 IA32_Test_Rm_Reg(jit, reg, reg, MOD_REG);
188 jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_NZ, 0);
189 if (!(((CompData *)jit->data)->inline_level & JIT_INLINE_ERRORCHECKS))
191 //sub esp, 4 - correct stack for returning to non-inlined JIT
192 IA32_Sub_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
194 Write_Error(jit, SP_ERR_DIVIDE_BY_ZERO);
196 IA32_Send_Jump8_Here(jit, jmp);
199 //:TODO: FIX THIS FOR NEW EBP STUFF
200 void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg, bool firstcall)
202 CompData *data = (CompData *)jit->data;
204 /* :TODO: Should this be checking for below heaplow?
205 * The old JIT did not.
214 if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
216 /* If we're not in the initial generation phase,
217 * Write a call to the actual routine instead.
221 jitoffs_t call = IA32_Call_Imm32(jit, 0);
224 IA32_Write_Jump32(jit, call, data->jit_verify_addr_eax);
225 } else if (reg == REG_EDX) {
226 IA32_Write_Jump32(jit, call, data->jit_verify_addr_edx);
231 } else if (firstcall) {
232 /* Inline + initial gen == no code */
243 //memaccess: (write error)
245 IA32_Cmp_Reg_Rm_Disp8(jit, reg, AMX_REG_INFO, AMX_INFO_STACKTOP);
246 jitoffs_t jmp1 = IA32_Jump_Cond_Imm8(jit, CC_AE, 0);
247 IA32_Cmp_Reg_Rm_Disp8(jit, reg, AMX_REG_INFO, AMX_INFO_HEAP);
248 jitoffs_t jmp2 = IA32_Jump_Cond_Imm8(jit, CC_B, 0);
249 IA32_Lea_Reg_DispRegMult(jit, AMX_REG_TMP, reg, AMX_REG_DAT, NOSCALE);
250 IA32_Cmp_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
251 jitoffs_t jmp3 = IA32_Jump_Cond_Imm8(jit, CC_AE, 0);
252 IA32_Send_Jump8_Here(jit, jmp1);
253 Write_Error(jit, SP_ERR_MEMACCESS);
254 IA32_Send_Jump8_Here(jit, jmp2);
255 IA32_Send_Jump8_Here(jit, jmp3);
262 void Write_BoundsCheck(JitWriter *jit)
264 CompData *data = (CompData *)jit->data;
265 bool always_inline = ((data->inline_level & JIT_INLINE_ERRORCHECKS) == JIT_INLINE_ERRORCHECKS);
267 /* :TODO: break out on high -O level? */
271 if (data->jit_bounds)
273 /* just generate the call */
276 IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, jit->read_cell());
277 jitoffs_t call = IA32_Call_Imm32(jit, 0);
278 IA32_Write_Jump32(jit, call, data->jit_bounds);
285 IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_PRI, 0);
286 jitoffs_t jmp1 = IA32_Jump_Cond_Imm8(jit, CC_L, 0);
287 //:TODO: make sure this is right order
288 IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_TMP, MOD_REG);
289 jitoffs_t jmp2 = IA32_Jump_Cond_Imm8(jit, CC_G, 0);
291 IA32_Send_Jump8_Here(jit, jmp1);
292 IA32_Send_Jump8_Here(jit, jmp2);
293 Write_Error(jit, SP_ERR_ARRAY_BOUNDS);
298 IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_PRI, 0);
299 jitoffs_t jmp1 = IA32_Jump_Cond_Imm8(jit, CC_L, 0);
302 cell_t val = jit->read_cell();
303 if (val < SCHAR_MAX && val > SCHAR_MIN)
304 IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_PRI, (jit_int8_t)val);
306 IA32_Cmp_Eax_Imm32(jit, val);
307 jitoffs_t jmp2 = IA32_Jump_Cond_Imm8(jit, CC_G, 0);
309 jitoffs_t cont = IA32_Jump_Imm8(jit, 0);
311 IA32_Send_Jump8_Here(jit, jmp1);
312 IA32_Send_Jump8_Here(jit, jmp2);
313 Write_Error(jit, SP_ERR_ARRAY_BOUNDS);
315 IA32_Send_Jump8_Here(jit, cont);
319 void Write_CheckMargin_Heap(JitWriter *jit)
321 CompData *data = (CompData *)jit->data;
323 bool always_inline = ((data->inline_level & JIT_INLINE_ERRORCHECKS) == JIT_INLINE_ERRORCHECKS);
325 if (!always_inline && data->jit_chkmargin_heap)
327 /* just generate the call */
328 jitoffs_t call = IA32_Call_Imm32(jit, 0);
329 IA32_Write_Jump32(jit, call, data->jit_chkmargin_heap);
334 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
335 IA32_Cmp_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAPLOW);
336 jitoffs_t hm = IA32_Jump_Cond_Imm8(jit, CC_L, 0);
337 //lea ecx, [ebp+ecx+STACK_MARGIN]
342 IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_TMP, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, STACK_MARGIN);
343 IA32_Cmp_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
344 jitoffs_t hl = IA32_Jump_Cond_Imm8(jit, CC_G, 0);
348 cont = IA32_Jump_Imm8(jit, 0);
353 IA32_Send_Jump8_Here(jit, hm);
354 Write_Error(jit, SP_ERR_HEAPMIN);
356 IA32_Send_Jump8_Here(jit, hl);
357 Write_Error(jit, SP_ERR_HEAPLOW);
361 IA32_Send_Jump8_Here(jit, cont);
366 void Write_CheckMargin_Stack(JitWriter *jit)
368 /* this is small, so we always inline it.
372 IA32_Cmp_Reg_Rm_Disp8(jit, AMX_REG_STK, AMX_REG_INFO, AMX_INFO_STACKTOP);
373 jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_LE, 0);
374 if (!(((CompData *)jit->data)->inline_level & JIT_INLINE_ERRORCHECKS))
376 //sub esp, 4 - correct stack for returning to non-inlined JIT
377 IA32_Sub_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
379 Write_Error(jit, SP_ERR_STACKMIN);
381 IA32_Send_Jump8_Here(jit, jmp);
384 void Macro_PushN_Addr(JitWriter *jit, int i)
389 // lea ecx, [eax+<val>]
390 // mov [edi-4*i], ecx
396 IA32_Push_Reg(jit, AMX_REG_PRI);
397 IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_INFO, MOD_MEM_REG);
400 val = jit->read_cell();
401 if (val < SCHAR_MAX && val > SCHAR_MIN)
402 IA32_Lea_DispRegImm8(jit, AMX_REG_TMP, AMX_REG_PRI, (jit_int8_t)val);
404 IA32_Lea_DispRegImm32(jit, AMX_REG_TMP, AMX_REG_PRI, val);
405 IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
407 IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
408 IA32_Pop_Reg(jit, AMX_REG_PRI);
411 void Macro_PushN_S(JitWriter *jit, int i)
414 // mov ecx, [ebx+<val>]
415 // mov [edi-4*i], ecx
422 val = jit->read_cell();
423 if (val < SCHAR_MAX && val > SCHAR_MIN)
424 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
426 IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
427 IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
429 IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
432 void Macro_PushN_C(JitWriter *jit, int i)
435 // mov [edi-4*i], <val>
441 IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_STK, jit->read_cell(), -4*n);
443 IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
446 void Macro_PushN(JitWriter *jit, int i)
449 // mov ecx, [ebp+<val>]
450 // mov [edi-4*i], ecx
457 val = jit->read_cell();
458 if (val < SCHAR_MAX && val > SCHAR_MIN)
459 IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
461 IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
462 IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
464 IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
469 memset(OpAdvTable, -1, sizeof(OpAdvTable));
471 /* instructions with 5 parameters */
472 OpAdvTable[OP_PUSH5_C] = sizeof(cell_t)*5;
473 OpAdvTable[OP_PUSH5] = sizeof(cell_t)*5;
474 OpAdvTable[OP_PUSH5_S] = sizeof(cell_t)*5;
475 OpAdvTable[OP_PUSH5_ADR] = sizeof(cell_t)*5;
477 /* instructions with 4 parameters */
478 OpAdvTable[OP_PUSH4_C] = sizeof(cell_t)*4;
479 OpAdvTable[OP_PUSH4] = sizeof(cell_t)*4;
480 OpAdvTable[OP_PUSH4_S] = sizeof(cell_t)*4;
481 OpAdvTable[OP_PUSH4_ADR] = sizeof(cell_t)*4;
483 /* instructions with 3 parameters */
484 OpAdvTable[OP_PUSH3_C] = sizeof(cell_t)*3;
485 OpAdvTable[OP_PUSH3] = sizeof(cell_t)*3;
486 OpAdvTable[OP_PUSH3_S] = sizeof(cell_t)*3;
487 OpAdvTable[OP_PUSH3_ADR] = sizeof(cell_t)*3;
489 /* instructions with 2 parameters */
490 OpAdvTable[OP_PUSH2_C] = sizeof(cell_t)*2;
491 OpAdvTable[OP_PUSH2] = sizeof(cell_t)*2;
492 OpAdvTable[OP_PUSH2_S] = sizeof(cell_t)*2;
493 OpAdvTable[OP_PUSH2_ADR] = sizeof(cell_t)*2;
494 OpAdvTable[OP_LOAD_BOTH] = sizeof(cell_t)*2;
495 OpAdvTable[OP_LOAD_S_BOTH] = sizeof(cell_t)*2;
496 OpAdvTable[OP_CONST] = sizeof(cell_t)*2;
497 OpAdvTable[OP_CONST_S] = sizeof(cell_t)*2;
498 OpAdvTable[OP_SYSREQ_N] = sizeof(cell_t)*2;
500 /* instructions with 1 parameter */
501 OpAdvTable[OP_LOAD_PRI] = sizeof(cell_t);
502 OpAdvTable[OP_LOAD_ALT] = sizeof(cell_t);
503 OpAdvTable[OP_LOAD_S_PRI] = sizeof(cell_t);
504 OpAdvTable[OP_LOAD_S_ALT] = sizeof(cell_t);
505 OpAdvTable[OP_LREF_PRI] = sizeof(cell_t);
506 OpAdvTable[OP_LREF_ALT] = sizeof(cell_t);
507 OpAdvTable[OP_LREF_S_PRI] = sizeof(cell_t);
508 OpAdvTable[OP_LREF_S_ALT] = sizeof(cell_t);
509 OpAdvTable[OP_CONST_PRI] = sizeof(cell_t);
510 OpAdvTable[OP_CONST_ALT] = sizeof(cell_t);
511 OpAdvTable[OP_ADDR_PRI] = sizeof(cell_t);
512 OpAdvTable[OP_ADDR_ALT] = sizeof(cell_t);
513 OpAdvTable[OP_STOR_PRI] = sizeof(cell_t);
514 OpAdvTable[OP_STOR_ALT] = sizeof(cell_t);
515 OpAdvTable[OP_STOR_S_PRI] = sizeof(cell_t);
516 OpAdvTable[OP_STOR_S_ALT] = sizeof(cell_t);
517 OpAdvTable[OP_SREF_PRI] = sizeof(cell_t);
518 OpAdvTable[OP_SREF_ALT] = sizeof(cell_t);
519 OpAdvTable[OP_SREF_S_PRI] = sizeof(cell_t);
520 OpAdvTable[OP_SREF_S_ALT] = sizeof(cell_t);
521 OpAdvTable[OP_LIDX_B] = sizeof(cell_t);
522 OpAdvTable[OP_IDXADDR_B] = sizeof(cell_t);
523 OpAdvTable[OP_PUSH_C] = sizeof(cell_t);
524 OpAdvTable[OP_PUSH] = sizeof(cell_t);
525 OpAdvTable[OP_PUSH_S] = sizeof(cell_t);
526 OpAdvTable[OP_STACK] = sizeof(cell_t);
527 OpAdvTable[OP_HEAP] = sizeof(cell_t);
528 OpAdvTable[OP_SHL_C_PRI] = sizeof(cell_t);
529 OpAdvTable[OP_SHL_C_ALT] = sizeof(cell_t);
530 OpAdvTable[OP_SHR_C_PRI] = sizeof(cell_t);
531 OpAdvTable[OP_SHR_C_ALT] = sizeof(cell_t);
532 OpAdvTable[OP_ADD_C] = sizeof(cell_t);
533 OpAdvTable[OP_SMUL_C] = sizeof(cell_t);
534 OpAdvTable[OP_ZERO] = sizeof(cell_t);
535 OpAdvTable[OP_ZERO_S] = sizeof(cell_t);
536 OpAdvTable[OP_EQ_C_PRI] = sizeof(cell_t);
537 OpAdvTable[OP_EQ_C_ALT] = sizeof(cell_t);
538 OpAdvTable[OP_INC] = sizeof(cell_t);
539 OpAdvTable[OP_INC_S] = sizeof(cell_t);
540 OpAdvTable[OP_DEC] = sizeof(cell_t);
541 OpAdvTable[OP_DEC_S] = sizeof(cell_t);
542 OpAdvTable[OP_MOVS] = sizeof(cell_t);
543 OpAdvTable[OP_FILL] = sizeof(cell_t);
544 OpAdvTable[OP_HALT] = sizeof(cell_t);
545 OpAdvTable[OP_BOUNDS] = sizeof(cell_t);
546 OpAdvTable[OP_PUSH_ADR] = sizeof(cell_t);
547 OpAdvTable[OP_PUSH_HEAP_C] = sizeof(cell_t);
548 OpAdvTable[OP_SYSREQ_C] = sizeof(cell_t);
550 /* instructions with 0 parameters */
551 OpAdvTable[OP_LOAD_I] = 0;
552 OpAdvTable[OP_STOR_I] = 0;
553 OpAdvTable[OP_LIDX] = 0;
554 OpAdvTable[OP_IDXADDR] = 0;
555 OpAdvTable[OP_MOVE_PRI] = 0;
556 OpAdvTable[OP_MOVE_ALT] = 0;
557 OpAdvTable[OP_XCHG] = 0;
558 OpAdvTable[OP_PUSH_PRI] = 0;
559 OpAdvTable[OP_PUSH_ALT] = 0;
560 OpAdvTable[OP_POP_PRI] = 0;
561 OpAdvTable[OP_POP_ALT] = 0;
562 OpAdvTable[OP_PROC] = 0;
563 OpAdvTable[OP_RET] = 0;
564 OpAdvTable[OP_RETN] = 0;
565 OpAdvTable[OP_CALL_PRI] = 0;
566 OpAdvTable[OP_SHL] = 0;
567 OpAdvTable[OP_SHR] = 0;
568 OpAdvTable[OP_SSHR] = 0;
569 OpAdvTable[OP_SMUL] = 0;
570 OpAdvTable[OP_SDIV] = 0;
571 OpAdvTable[OP_SDIV_ALT] = 0;
572 OpAdvTable[OP_ADD] = 0;
573 OpAdvTable[OP_SUB] = 0;
574 OpAdvTable[OP_SUB_ALT] = 0;
575 OpAdvTable[OP_AND] = 0;
576 OpAdvTable[OP_OR] = 0;
577 OpAdvTable[OP_XOR] = 0;
578 OpAdvTable[OP_NOT] = 0;
579 OpAdvTable[OP_NEG] = 0;
580 OpAdvTable[OP_INVERT] = 0;
581 OpAdvTable[OP_ZERO_PRI] = 0;
582 OpAdvTable[OP_ZERO_ALT] = 0;
583 OpAdvTable[OP_SIGN_PRI] = 0;
584 OpAdvTable[OP_SIGN_ALT] = 0;
585 OpAdvTable[OP_EQ] = 0;
586 OpAdvTable[OP_NEQ] = 0;
587 OpAdvTable[OP_SLESS] = 0;
588 OpAdvTable[OP_SLEQ] = 0;
589 OpAdvTable[OP_SGRTR] = 0;
590 OpAdvTable[OP_SGEQ] = 0;
591 OpAdvTable[OP_INC_PRI] = 0;
592 OpAdvTable[OP_INC_ALT] = 0;
593 OpAdvTable[OP_INC_I] = 0;
594 OpAdvTable[OP_DEC_PRI] = 0;
595 OpAdvTable[OP_DEC_ALT] = 0;
596 OpAdvTable[OP_DEC_I] = 0;
597 OpAdvTable[OP_JUMP_PRI] = 0;
598 OpAdvTable[OP_SWAP_PRI] = 0;
599 OpAdvTable[OP_SWAP_ALT] = 0;
600 OpAdvTable[OP_NOP] = 0;
601 OpAdvTable[OP_BREAK] = 0;
602 OpAdvTable[OP_HEAP_PRI] = 0;
603 OpAdvTable[OP_POP_HEAP_PRI] = 0;
604 OpAdvTable[OP_SYSREQ_PRI] = 0;
606 /* opcodes that need relocation */
607 OpAdvTable[OP_CALL] = -2;
608 OpAdvTable[OP_JUMP] = -2;
609 OpAdvTable[OP_JZER] = -2;
610 OpAdvTable[OP_JNZ] = -2;
611 OpAdvTable[OP_JEQ] = -2;
612 OpAdvTable[OP_JNEQ] = -2;
613 OpAdvTable[OP_JSLESS] = -2;
614 OpAdvTable[OP_JSLEQ] = -2;
615 OpAdvTable[OP_JSGRTR] = -2;
616 OpAdvTable[OP_JSGEQ] = -2;
617 OpAdvTable[OP_SWITCH] = -2;
619 /* opcodes that are totally invalid */
620 /* :TODO: make an alternate table if USE_UNGEN_OPCODES is on? */
621 OpAdvTable[OP_FILE] = -3;
622 OpAdvTable[OP_SYMBOL] = -3;
623 OpAdvTable[OP_LINE] = -3;
624 OpAdvTable[OP_SRANGE] = -3;
625 OpAdvTable[OP_SYMTAG] = -3;
626 OpAdvTable[OP_SYSREQ_D] = -3;
627 OpAdvTable[OP_SYSREQ_ND] = -3;
628 OpAdvTable[OP_PUSH_R] = -3;
629 OpAdvTable[OP_LODB_I] = -3;
630 OpAdvTable[OP_STRB_I] = -3;
631 OpAdvTable[OP_LCTRL] = -3;
632 OpAdvTable[OP_SCTRL] = -3;
633 OpAdvTable[OP_ALIGN_PRI] = -3;
634 OpAdvTable[OP_ALIGN_ALT] = -3;
635 OpAdvTable[OP_JREL] = -3;
636 OpAdvTable[OP_CMPS] = -3;
637 OpAdvTable[OP_UMUL] = -3;
638 OpAdvTable[OP_UDIV] = -3;
639 OpAdvTable[OP_UDIV_ALT] = -3;
640 OpAdvTable[OP_LESS] = -3;
641 OpAdvTable[OP_LEQ] = -3;
642 OpAdvTable[OP_GRTR] = -3;
643 OpAdvTable[OP_GEQ] = -3;
644 OpAdvTable[OP_JLESS] = -3;
645 OpAdvTable[OP_JLEQ] = -3;
646 OpAdvTable[OP_JGRTR] = -3;
647 OpAdvTable[OP_JGEQ] = -3;