📄 opcodes
字号:
# Opcode definitions.# Copyright (C) 2001-2002 Darius Bacon## Syntax of this file:# <range> <C-name> <stack inputs> <name> <immediate operands> -- <stack outputs>## range indicates which of phases 1 through 3 the op has meaning in.# 1: assembly code# 2: object code# 3: executable code## ?? for inputs or outputs means a dynamic stack effect depending on the# immediate operands.## u1, u2, ... for unsigned ints.# n1, n2, ... for signed.# p1, p2, ... for address (`pointer').## `NEXT' in the body means advance the program counter past this# instruction. If the body has no NEXT anywhere, it's implicit at# the end.## A comment line must have a `#' in the *first* column.23 PUSH PUSH n1 -- n2 n2 = n1;3 GRAB ?? GRAB u1 -- unsigned int i; sp -= u1; rp -= u1; for (i = 0; i < u1; ++i) rp[u1 - 1 - i] = (sp+1)[i];23 DROP DROP u1 -- rp += u1;23 LOCAL LOCAL u1 -- n2 n2 = rp[u1];123 ADD n1 n2 + -- n3 n3 = n1 + n2;123 SUB n1 n2 - -- n3 n3 = n1 - n2;123 IMUL n1 n2 * -- n3 n3 = n1 * n2;123 UMUL u1 u2 u* -- u3 u3 = u1 * u2;123 IDIV n1 n2 /mod -- n3 n4 if (n2 == 0) die ("Division by 0"); n3 = IDIV0 (n1, n2); n4 = IMOD0 (n1, n2);123 UDIV u1 u2 u/mod -- u3 u4 if (u2 == 0) die ("Division by 0"); u3 = u1 / u2; u4 = u1 % u2;123 AND u1 u2 and -- u3 u3 = u1 & u2;123 IOR u1 u2 or -- u3 u3 = u1 | u2;123 XOR u1 u2 xor -- u3 u3 = u1 ^ u2;123 LSHIFT n1 u2 << -- n3 n3 = (word_bits <= u2 ? 0 : n1 << u2); /* Would it be `better' to shift by u2%32 instead of clamping the count at 32? */123 RSHIFT n1 u2 >> -- n3 n3 = (word_bits <= u2 ? 0 : ASR (n1, u2));123 URSHIFT u1 u2 >>> -- u3 u3 = (word_bits <= u2 ? 0 : u1 >> u2);123 EQ n1 n2 = -- n3 n3 = -(n1 == n2);123 LT n1 n2 < -- n3 n3 = -(n1 < n2);123 ULT u1 u2 u< -- n3 n3 = -(u1 < u2);123 FETCH p1 @ -- n2 if (data_size <= p1) die ("Out of bounds in @ [%d]", p1); if (0 != (p1 & 3)) die ("Unaligned access in @ [%d]", p1); n2 = *(i32 *)(data + p1);123 STORE n1 p2 ! -- if (data_size <= p2) die ("Out of bounds in ! [%d]", p2); if (0 != (p2 & 3)) die ("Unaligned access in ! [%d]", p2); *(i32 *)(data + p2) = n1;123 CFETCH p1 c@ -- n2 if (data_size <= (endianness ^ p1)) die ("Out of bounds in c@ [%d]", p1); n2 = data[endianness ^ p1];123 CSTORE n1 p2 c! -- if (data_size <= (endianness ^ p2)) die ("Out of bounds in c! [%d]", p2); data[endianness ^ p2] = n1;# The CALL and TAILCALL instructions should have a stack effect of # ?? -- ?? if you're thinking of static analysis, but since there's no# stack effect inside the instruction at runtime it's simpler to# specify them that way. This is okay because the static analysis# uses special code.3 TAILCALL TAILCALL u1 -- if (fuel-- == 0) die ("Out of fuel"); pc = (i32 *) u1; /* The max stack need of the function called is in its first word: */ if (rp - (sp+1) < *pc++) die ("Stack overflow"); if (0) NEXT; /* inhibits the implicit NEXT after this */23 CALL CALL u1 -- if (fuel-- == 0) die ("Out of fuel"); NEXT; *--rp = (i32) pc; pc = (i32 *) u1; if (rp - (sp+1) < *pc++) die ("Stack overflow");3 RETURN RETURN -- pc = (i32 *) *rp++; if (0) NEXT; /* inhibits the implicit NEXT after this */2 BEGIN BEGIN -- unreachable (); /* TODO: fix so stage-2 ops aren't in vm code */2 ELSE ELSE -- unreachable ();2 THEN THEN -- unreachable ();123 EMIT n1 emit -- putchar (n1);123 ABSORB absorb -- n1 n1 = getchar ();123 save save -- n1 if (!idel_development_enabled) die ("Unsupported, still-unsafe operation encountered"); NEXT; vm->sp = sp+1; vm->rp = rp - 1; rp[-1] = (i32) pc; save_vm_state (vm); n1 = 0;# None of the following instructions is part of the public API3 JUMP JUMP u1 -- pc = (i32 *) u1; if (0) NEXT; /* inhibits the implicit NEXT after this */3 BRANCH n1 BRANCH u2 -- NEXT; if (0 == n1) pc = (i32 *) u2;3 HALT n1 HALT -- --rp; /* push the sentinel back on the return stack */ vm->pc = pc; return n1; if (0) NEXT; /* inhibits the implicit NEXT after this */3 TALLY TALLY u1 -- vm->tallies[u1].count++;# Specializations of some primitives to particular immediate arguments# (for efficiency):3 PUSH_1 PUSH_1 -- n1 n1 = -1;3 PUSH0 PUSH0 -- n1 n1 = 0;3 PUSH1 PUSH1 -- n1 n1 = 1;3 PUSH2 PUSH2 -- n1 n1 = 2;3 PUSH3 PUSH3 -- n1 n1 = 3;3 PUSH4 PUSH4 -- n1 n1 = 4;3 GRAB1 n1 GRAB1 -- rp -= 1; rp [1 - 1 - 0] = n1;3 GRAB2 n1 n2 GRAB2 -- rp -= 2; rp [2 - 1 - 0] = n1; rp [2 - 1 - 1] = n2;3 GRAB3 n1 n2 n3 GRAB3 -- rp -= 3; rp [3 - 1 - 0] = n1; rp [3 - 1 - 1] = n2; rp [3 - 1 - 2] = n3;3 GRAB4 n1 n2 n3 n4 GRAB4 -- rp -= 4; rp [4 - 1 - 0] = n1; rp [4 - 1 - 1] = n2; rp [4 - 1 - 2] = n3; rp [4 - 1 - 3] = n4;3 DROP1 DROP1 -- rp += 1;3 DROP2 DROP2 -- rp += 2;3 DROP3 DROP3 -- rp += 3;3 DROP4 DROP4 -- rp += 4;3 LOCAL0 LOCAL0 -- n2 n2 = rp[0];3 LOCAL1 LOCAL1 -- n2 n2 = rp[1];3 LOCAL2 LOCAL2 -- n2 n2 = rp[2];3 LOCAL3 LOCAL3 -- n2 n2 = rp[3];3 BRANCH2 n1 BRANCH2 -- NEXT; if (0 == n1) pc += 2;3 BRANCH3 n1 BRANCH3 -- NEXT; if (0 == n1) pc += 3;3 BRANCH4 n1 BRANCH4 -- NEXT; if (0 == n1) pc += 4;3 BRANCH5 n1 BRANCH5 -- NEXT; if (0 == n1) pc += 5;3 BRANCH6 n1 BRANCH6 -- NEXT; if (0 == n1) pc += 6;3 BRANCH7 n1 BRANCH7 -- NEXT; if (0 == n1) pc += 7;3 BRANCH8 n1 BRANCH8 -- NEXT; if (0 == n1) pc += 8;3 BRANCH9 n1 BRANCH9 -- NEXT; if (0 == n1) pc += 9;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -