/* opcode.h -- the 32 core opcodes. * * DECOMPOSITION.md section 1.3. "Opcode numbering follows the F18. Two names * differ from Moore's: F18 `-` is renamed `inv` and F18 `or` (which is * exclusive-or) is renamed `xor`, so instruction names never collide with * FORTH-79 word names." * * Those two renames are load-bearing, not cosmetic: FORTH-79 has words named * `-` and `OR`, and the DECOMPOSITION table would otherwise have two distinct * meanings per name. The renames are therefore asserted against the FORTH * name set in tests/test_iword.c, so a future edit that reintroduces a * collision fails a test rather than silently producing an ambiguous table. * * Branch opcodes are marked because the instruction-word format depends on * them: only these five take a target out of the low bits of their slot, and * only they are legal outside the low four slots (section 1.2). */ #ifndef V4_OPCODE_H #define V4_OPCODE_H typedef enum { V4_OP_SEMI = 0x00, /* ; return */ V4_OP_EX = 0x01, /* ex swap P and R */ V4_OP_JUMP = 0x02, /* jump a */ V4_OP_CALL = 0x03, /* call a */ V4_OP_UNEXT = 0x04, /* unext */ V4_OP_NEXT = 0x05, /* next a */ V4_OP_IF = 0x06, /* if a */ V4_OP_MINUS_IF = 0x07, /* -if a */ V4_OP_FETCH_P = 0x08, /* @p literal */ V4_OP_FETCH_INC= 0x09, /* @+ */ V4_OP_FETCH_B = 0x0A, /* @b */ V4_OP_FETCH_A = 0x0B, /* @ */ V4_OP_STORE_P = 0x0C, /* !p */ V4_OP_STORE_INC= 0x0D, /* !+ */ V4_OP_STORE_B = 0x0E, /* !b */ V4_OP_STORE_A = 0x0F, /* ! */ V4_OP_MUL_STEP = 0x10, /* +* multiply step, D-3 */ V4_OP_TWO_STAR = 0x11, /* 2* */ V4_OP_TWO_SLASH= 0x12, /* 2/ */ V4_OP_INV = 0x13, /* inv (F18 `-`) */ V4_OP_ADD = 0x14, /* + */ V4_OP_AND = 0x15, /* and */ V4_OP_XOR = 0x16, /* xor (F18 `or`) */ V4_OP_DROP = 0x17, /* drop */ V4_OP_DUP = 0x18, /* dup */ V4_OP_RPOP = 0x19, /* pop R to data stack */ V4_OP_OVER = 0x1A, /* over */ V4_OP_PUSH_A = 0x1B, /* a */ V4_OP_NOP = 0x1C, /* nop */ V4_OP_PUSH = 0x1D, /* push T to return stack */ V4_OP_BANG_B = 0x1E, /* b! B <- T */ V4_OP_BANG_A = 0x1F, /* a! A <- T */ V4_OPCODE_COUNT = 0x20 } v4_opcode; /* True for the five opcodes that take a branch target from the low bits of * their slot: jump, call, next, if, -if. Everything else ignores the low * bits of its slot, which is what makes a non-branch slot's low bits * free for the compiler to use as a compressed argument. */ int v4_op_is_branch(unsigned op); #endif /* V4_OPCODE_H */