Last active
April 8, 2016 17:11
-
-
Save wsuzume/2b8a189df5a4aabfc5b30c16ad81e4d5 to your computer and use it in GitHub Desktop.
procyon virtual machine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include "type.h" | |
#include "rgsmap.h" | |
#define OPRND1(var) ((var>>8)&0x0000000f) | |
#define OPRND2(var) (var&0x0000000f) | |
//intptr_t型でスタックポインタを取得 | |
#define GETCURSOL(stk,rgs) (stk+(intptr_t)(*(intptr_t *)(rgs+RSP))) | |
//intptr_t型でベースポインタを取得 | |
#define GETBASE(stk,rgs) (stk+(intptr_t)(*(intptr_t *)(rgs+RBP))) | |
//相対アドレスからオート変数のアドレスをintptr_t型で取得 | |
#define GETATVAR(stk,rgs,ptr) (intptr_t)((*(intptr_t *)(rgs+RBP))+ptr+stk) | |
#define BINARYOPERATOR(inst,rgs,type,op) \ | |
*(type *)(rgs+((inst>>8)&0x0000000f)) op *(type *)(rgs+(inst&0x0000000f)) | |
#define BASICOPERATOR(tnum,type,inst,rgs,flag,tracer) \ | |
case ADD_##tnum: BINARYOPERATOR(inst, rgs, type, +=); tracer += 4; continue; \ | |
case SUB_##tnum: BINARYOPERATOR(inst, rgs, type, -=); tracer += 4; continue; \ | |
case MUL_##tnum: BINARYOPERATOR(inst, rgs, type, *=); tracer += 4; continue; \ | |
case DIV_##tnum: BINARYOPERATOR(inst, rgs, type, /=); tracer += 4; continue; \ | |
case EQ_##tnum: flag = BINARYOPERATOR(inst, rgs, type, ==); tracer += 4; continue; \ | |
case NEQ_##tnum: flag = BINARYOPERATOR(inst, rgs, type, !=); tracer += 4; continue; \ | |
case LT_##tnum: flag = BINARYOPERATOR(inst, rgs, type, <); tracer += 4; continue; \ | |
case GT_##tnum: flag = BINARYOPERATOR(inst, rgs, type, >); tracer += 4; continue; \ | |
case LTEQ_##tnum: flag = BINARYOPERATOR(inst, rgs, type, <=); tracer += 4; continue; \ | |
case GTEQ_##tnum: flag = BINARYOPERATOR(inst, rgs, type, >=); tracer += 4; continue | |
#define BASICOPENUMERATOR(tnum) \ | |
ADD_##tnum, \ | |
SUB_##tnum, \ | |
MUL_##tnum, \ | |
DIV_##tnum, \ | |
EQ_##tnum, \ | |
NEQ_##tnum, \ | |
LT_##tnum, \ | |
GT_##tnum, \ | |
LTEQ_##tnum, \ | |
GTEQ_##tnum | |
#define BASICBITOPERATOR(tnum,type,inst,rgs,flag,tracer) \ | |
case OR##tnum: BINARYOPERATOR(inst, rgs, type, |=); tracer += 4; continue; \ | |
case XOR##tnum: BINARYOPERATOR(inst, rgs, type, ^=); tracer += 4; continue; \ | |
case AND##tnum: BINARYOPERATOR(inst, rgs, type, &=); tracer += 4; continue; \ | |
case NOT##tnum: *(type *)(rgs+((inst>>8)&0x0000000f)) = !(*(type *)(rgs+((inst>>8)&0x0000000f))); tracer += 4; continue; \ | |
case INV##tnum: *(type *)(rgs+((inst>>8)&0x0000000f)) = ~(*(type *)(rgs+((inst>>8)&0x0000000f))); tracer += 4; continue | |
#define BASICBITOPENUMERATOR(tnum) \ | |
OR##tnum, \ | |
XOR##tnum, \ | |
AND##tnum, \ | |
NOT##tnum, \ | |
INV##tnum | |
enum OPSDOUBLE { | |
END = 0, | |
BASICOPENUMERATOR(NAT), | |
MOD_NAT, | |
BASICOPENUMERATOR(INT), | |
MOD_INT, | |
BASICOPENUMERATOR(NAT8), | |
MOD_NAT8, | |
BASICOPENUMERATOR(NAT16), | |
MOD_NAT16, | |
BASICOPENUMERATOR(NAT32), | |
MOD_NAT32, | |
BASICOPENUMERATOR(NAT64), | |
MOD_NAT64, | |
BASICOPENUMERATOR(INT8), | |
MOD_INT8, | |
BASICOPENUMERATOR(INT16), | |
MOD_INT16, | |
BASICOPENUMERATOR(INT32), | |
MOD_INT32, | |
BASICOPENUMERATOR(INT64), | |
MOD_INT64, | |
BASICOPENUMERATOR(BYTE), | |
MOD_BYTE, | |
BASICOPENUMERATOR(WORD), | |
MOD_WORD, | |
BASICOPENUMERATOR(CHAR), | |
MOD_CHAR, | |
BASICOPENUMERATOR(INDEX), | |
MOD_INDEX, | |
BASICOPENUMERATOR(ADDRESS), | |
MOD_ADDRESS, | |
BASICOPENUMERATOR(FLOAT), | |
//MOD_FLOAT, | |
BASICOPENUMERATOR(DOUBLE), | |
//MOD_DOUBLE, | |
OR, XOR, AND, NOT, INV, | |
BASICBITOPENUMERATOR(8), | |
BASICBITOPENUMERATOR(16), | |
BASICBITOPENUMERATOR(32), | |
BASICBITOPENUMERATOR(64), | |
BASICBITOPENUMERATOR(BOOL), | |
SLA, SRA, | |
SLL, SRL, | |
MOV, MOV8, MOV16, MOV32, MOV64, | |
ASN, ASN8, ASN16, ASN32, ASN64, | |
LD, LD8, LD16, LD32, LD64, | |
LAD, LAD8, LAD16, LAD32, LAD64, | |
FLAG, | |
FLGSET, | |
PUSH, | |
POP, | |
//PUSHN, | |
//POPN, | |
ATASN, ATASN8, ATASN16, ATASN32, ATASN64, | |
ATLAD, ATLAD8, ATLAD16, ATLAD32, ATLAD64, | |
JMP, JTF, JNT, | |
FPTR, | |
CALL, | |
RET, | |
CALLC, | |
}; | |
#define NOP 0x60 | |
#define PRTRGS 0xff | |
//mmapに切り替えるかもしれないのでオーバーラップしておく | |
void *vmap(size_t size) | |
{ | |
return malloc(size); | |
} | |
int prvm(int argc, char *argv[], void *code) | |
{ | |
intptr_t rgs = (intptr_t)calloc(256, 1); //仮想レジスタ | |
intptr_t stk = (intptr_t)vmap(8 * 1024 * 1024); //コールスタック | |
uint8_t *opcode = (uint8_t *)code; | |
uint32_t inst; | |
//条件分岐用フラグレジスタ | |
//仮想レジスタのEFLAGSレジスタが使いにくいため。 | |
//EFLAGSレジスタは仮想レジスタ末尾に配置するが、その保証はしない。 | |
int flag = 0; | |
//レジスタのBPとSPを初期化 | |
*(intptr_t *)(rgs+RBP) = (intptr_t)sizeof(intptr_t); | |
*(intptr_t *)(rgs+RSP) = (intptr_t)sizeof(intptr_t); | |
while(1) { | |
//まずは4byte命令と仮定して読み取り | |
//メモリIOの回数は極力減らす設計に(命令と引数はシフト演算で分解) | |
inst = *(uint32_t *)opcode; | |
//1byte命令はすべて0x0fより大きい自然数が割り当てられている | |
if ((inst >> 24) <= 0x0f) { | |
//2byte命令 | |
switch (inst >> 16) { | |
case END: goto PRVMEND; | |
BASICOPERATOR(NAT, Nat, inst, rgs, flag, opcode); | |
case MOD_NAT: BINARYOPERATOR(inst, rgs, Nat, %=); opcode += 4; continue; | |
BASICOPERATOR(INT, Int, inst, rgs, flag, opcode); | |
case MOD_INT: BINARYOPERATOR(inst, rgs, Int, %=); opcode += 4; continue; | |
BASICOPERATOR(NAT8, Nat8, inst, rgs, flag, opcode); | |
case MOD_NAT8: BINARYOPERATOR(inst, rgs, Nat8, %=); opcode += 4; continue; | |
BASICOPERATOR(NAT16, Nat16, inst, rgs, flag, opcode); | |
case MOD_NAT16: BINARYOPERATOR(inst, rgs, Nat16, %=); opcode += 4; continue; | |
BASICOPERATOR(NAT32, Nat32, inst, rgs, flag, opcode); | |
case MOD_NAT32: BINARYOPERATOR(inst, rgs, Nat32, %=); opcode += 4; continue; | |
BASICOPERATOR(NAT64, Nat64, inst, rgs, flag, opcode); | |
case MOD_NAT64: BINARYOPERATOR(inst, rgs, Nat64, %=); opcode += 4; continue; | |
BASICOPERATOR(INT8, Int8, inst, rgs, flag, opcode); | |
case MOD_INT8: BINARYOPERATOR(inst, rgs, Int8, %=); opcode += 4; continue; | |
BASICOPERATOR(INT16, Int16, inst, rgs, flag, opcode); | |
case MOD_INT16: BINARYOPERATOR(inst, rgs, Int16, %=); opcode += 4; continue; | |
BASICOPERATOR(INT32, Int32, inst, rgs, flag, opcode); | |
case MOD_INT32: BINARYOPERATOR(inst, rgs, Int32, %=); opcode += 4; continue; | |
BASICOPERATOR(INT64, Int64, inst, rgs, flag, opcode); | |
case MOD_INT64: BINARYOPERATOR(inst, rgs, Int64, %=); opcode += 4; continue; | |
BASICOPERATOR(BYTE, Byte, inst, rgs, flag, opcode); | |
case MOD_BYTE: BINARYOPERATOR(inst, rgs, Byte, %=); opcode += 4; continue; | |
BASICOPERATOR(WORD, Word, inst, rgs, flag, opcode); | |
case MOD_WORD: BINARYOPERATOR(inst, rgs, Word, %=); opcode += 4; continue; | |
BASICOPERATOR(CHAR, Char, inst, rgs, flag, opcode); | |
case MOD_CHAR: BINARYOPERATOR(inst, rgs, Char, %=); opcode += 4; continue; | |
BASICOPERATOR(INDEX, Index, inst, rgs, flag, opcode); | |
case MOD_INDEX: BINARYOPERATOR(inst, rgs, Index, %=); opcode += 4; continue; | |
BASICOPERATOR(ADDRESS, Address, inst, rgs, flag, opcode); | |
case MOD_ADDRESS: BINARYOPERATOR(inst, rgs, Address, %=); opcode += 4; continue; | |
BASICOPERATOR(FLOAT, Float, inst, rgs, flag, opcode); | |
BASICOPERATOR(DOUBLE, Double, inst, rgs, flag, opcode); | |
case OR: BINARYOPERATOR(inst, rgs, Nat, |=); opcode += 4; continue; | |
case XOR: BINARYOPERATOR(inst, rgs, Nat, ^=); opcode += 4; continue; | |
case AND: BINARYOPERATOR(inst, rgs, Nat, &=); opcode += 4; continue; | |
//この演算は2つ目のオペランドを無視する | |
case NOT: *(Nat *)(rgs+OPRND1(inst)) = !(*(Nat *)(rgs+OPRND1(inst)); opcode += 4; continue; | |
case INV: *(Nat *)(rgs+OPRND1(inst)) = ~(*(Nat *)(rgs+OPRND1(inst)); opcode += 4; continue; | |
BASICBITOPERATOR(8, Nat8, inst, rgs, flag, opcode); | |
BASICBITOPERATOR(16, Nat16, inst, rgs, flag, opcode); | |
BASICBITOPERATOR(32, Nat32, inst, rgs, flag, opcode); | |
BASICBITOPERATOR(64, Nat64, inst, rgs, flag, opcode); | |
BASICBITOPERATOR(BOOL, Bool, inst, rgs, flag, opcode); | |
//この演算は2つ目のオペランドが即値なので注意 | |
case SLA: *(Int *)(rgs+OPRND1(inst)) <<= rgs+OPRND2(inst); opcode += 4; continue; | |
case SRA: *(Int *)(rgs+OPRND1(inst)) >>= rgs+OPRND2(inst); opcode += 4; continue; | |
case SLL: *(Nat *)(rgs+OPRND1(inst)) <<= rgs+OPRND2(inst); opcode += 4; continue; | |
case SRL: *(Nat *)(rgs+OPRND1(inst)) >>= rgs+OPRND2(inst); opcode += 4; continue; | |
//レジスタ間コピー | |
case MOV: BINARYOPERATOR(inst, rgs, Nat, =); opcode += 4; continue; | |
case MOV8: BINARYOPERATOR(inst, rgs, Nat8, =); opcode += 4; continue; | |
case MOV16: BINARYOPERATOR(inst, rgs, Nat16, =); opcode += 4; continue; | |
case MOV32: BINARYOPERATOR(inst, rgs, Nat32, =); opcode += 4; continue; | |
case MOV64: BINARYOPERATOR(inst, rgs, Nat64, =); opcode += 4; continue; | |
//即値をレジスタにコピー | |
case ASN: *(Nat *)(rgs+OPRND1(inst)) = *(Nat *)(opcode+4); | |
opcode += 4+sizeof(Nat); continue; | |
case ASN8: *(Nat8 *)(rgs+OPRND1(inst)) = (Nat8)(rgs+OPRND2(inst)); | |
opcode += 4; continue; | |
case ASN16: *(Nat16 *)(rgs+OPRND1(inst)) = *(Nat16 *)(opcode+4); | |
opcode += 8; continue; | |
case ASN32: *(Nat32 *)(rgs+OPRND1(inst)) = *(Nat32 *)(opcode+4); | |
opcode += 8; continue; | |
case ASN64: *(Nat64 *)(rgs+OPRND1(inst)) = *(Nat64 *)(opcode+4); | |
opcode += 12; continue; | |
//オペランド1のレジスタへオペランド2のレジスタのアドレスからロード | |
case LD: *(Nat *)(rgs+OPRND1(inst)) = *(Nat *)(rgs+OPRND2(inst)); opcode += 4; continue; | |
case LD8: *(Nat8 *)(rgs+OPRND1(inst)) = *(Nat8 *)(rgs+OPRND2(inst)); opcode += 4; continue; | |
case LD16: *(Nat16 *)(rgs+OPRND1(inst)) = *(Nat16 *)(rgs+OPRND2(inst)); opcode += 4; continue; | |
case LD32: *(Nat32 *)(rgs+OPRND1(inst)) = *(Nat32 *)(rgs+OPRND2(inst)); opcode += 4; continue; | |
case LD64: *(Nat64 *)(rgs+OPRND1(inst)) = *(Nat64 *)(rgs+OPRND2(inst)); opcode += 4; continue; | |
//即値のアドレスからレジスタへロード | |
case LAD: *(Nat *)(rgs+OPRND1(inst)) = *(Nat *)(opcode+4); opcode += 4+sizeof(Nat *); continue; | |
case LAD8: *(Nat8 *)(rgs+OPRND1(inst)) = *(Nat8 *)(opcode+4); opcode += 4+sizeof(Nat8 *); continue; | |
case LAD16: *(Nat16 *)(rgs+OPRND1(inst)) = *(Nat16 *)(opcode+4); opcode += 4+sizeof(Nat16 *); continue; | |
case LAD32: *(Nat32 *)(rgs+OPRND1(inst)) = *(Nat32 *)(opcode+4); opcode += 4+sizeof(Nat32 *); continue; | |
case LAD64: *(Nat64 *)(rgs+OPRND1(inst)) = *(Nat64 *)(opcode+4); opcode += 4+sizeof(Nat64 *); continue; | |
//分岐用フラグをレジスタにコピー | |
case FLAG: *(int *)(rgs+OPRND1(inst)) = flag; opcode += 4; continue; | |
//レジスタから分岐用フラグへコピー | |
case FLGSET: flag = *(int *)(rgs+OPRND1(inst)); opcode += 4; continue; | |
//コールスタックの操作 | |
case PUSH: *(intptr_t *)GETCURSOL(stk,rgs) = *(intptr_t *)(rgs+OPRND1(inst)); | |
*(intptr_t *)(rgs+RSP) += sizeof(intptr_t); opcode += 4; continue; | |
case POP: *(intptr_t *)(rgs+RSP) -= sizeof(intptr_t); | |
*(intptr_t *)(rgs+OPRND1(inst)) = *(intptr_t *)GETCURSOL(stk,rgs); | |
opcode += 4; continue; | |
//オペランド1の値を相対アドレスからオート変数に代入 | |
case ATASN: *(Nat *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)) = *(Nat *)(rgs+OPRND1(inst)); | |
opcode += 4+sizeof(intptr_t); continue; | |
case ATASN8: *(Nat8 *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)) = *(Nat8 *)(rgs+OPRND1(inst)); | |
opcode += 4+sizeof(intptr_t); continue; | |
case ATASN16: *(Nat16 *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)) = *(Nat16 *)(rgs+OPRND1(inst)); | |
opcode += 4+sizeof(intptr_t); continue; | |
case ATASN32: *(Nat32 *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)) = *(Nat32 *)(rgs+OPRND1(inst)); | |
opcode += 4+sizeof(intptr_t); continue; | |
case ATASN64: *(Nat64 *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)) = *(Nat64 *)(rgs+OPRND1(inst)); | |
opcode += 4+sizeof(intptr_t); continue; | |
//相対アドレスからオート変数を読み取り | |
case ATLAD: *(Nat *)(rgs+OPRND1(inst)) = *(Nat *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)); | |
opcode += 4+sizeof(intptr_t); continue; | |
case ATLAD8: *(Nat8 *)(rgs+OPRND1(inst)) = *(Nat8 *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)); | |
opcode += 4+sizeof(intptr_t); continue; | |
case ATLAD16: *(Nat16 *)(rgs+OPRND1(inst)) = *(Nat16 *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)); | |
opcode += 4+sizeof(intptr_t); continue; | |
case ATLAD32: *(Nat32 *)(rgs+OPRND1(inst)) = *(Nat32 *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)); | |
opcode += 4+sizeof(intptr_t); continue; | |
case ATLAD64: *(Nat64 *)(rgs+OPRND1(inst)) = *(Nat64 *)GETATVAR(stk, rgs, *(intptr_t *)(opcode+4)); | |
opcode += 4+sizeof(intptr_t); continue; | |
//無条件ジャンプ | |
case JMP: opcode = (uint8_t *)(*(intptr_t *)(opcode+4)); continue; | |
//フラグがtrue(0以外)ならジャンプ | |
case JTF: opcode = flag ? (uint8_t *)(*(intptr_t *)(opcode+4)) : opcode+8; continue; | |
//フラグがfalse(0)ならジャンプ | |
case JNT: opcode = flag ? opcode+8 : (uint8_t *)(*(intptr_t *)(opcode+4)); continue; | |
//現在のスタックフレームが実行している関数のポインタを取得 | |
case FPTR: *(intptr_t *)(rgs+OPRND1(inst)) = *(intptr_t *)GETBASE(stk,rgs); opcode += 4; continue; | |
case CALL: | |
intptr_t oldframe = GETBASE(stk, rgs); | |
intptr_t function = *(intptr_t *)(opcode+4); | |
intptr_t retaddr = (intptr_t)(opcode+4+sizeof(intptr_t *)); | |
intptr_t cursol = GETCURSOL(stk,rgs); | |
*(intptr_t *)cursol = oldframe; | |
*(intptr_t *)(rgs+RBP) = cursol+sizeof(intptr_t); | |
*(intptr_t *)(cursol+sizeof(intptr_t)) = function; | |
*(intptr_t *)(rgs+RSP) = cursol+sizeof(intptr_t)*2; | |
*(intptr_t *)(cursol+sizeof(intptr_t)*3) = retaddr; | |
opcode = (uint8_t *)function; | |
continue; | |
case RET: | |
intptr_t curbase = GETBASE(stk,rgs); | |
intptr_t retaddr = *(intptr_t *)(curbase+sizeof(intptr_t)); | |
*(intptr_t *)(rgs+RBP) = *(intptr_t *)(curbase-sizeof(intptr_t)); | |
opcode = (uint8_t *)retaddr; | |
continue; | |
default: break; | |
} | |
} else { | |
//1byte命令(0x0f以上) | |
switch (inst >> 24) { | |
case NOP: opcode += 1; continue; //下手に詰めるとアラインメントが崩れる | |
//レジスタをプリント | |
case PRTRGS: continue; | |
default: break; | |
} | |
} | |
} | |
PRVMEND: | |
free((void *)rgs); | |
free((void *)stk); | |
return EXIT_SUCCESS; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
void *code = NULL; | |
return prvm(argc, argv, code); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define RAX 0x00 | |
#define EAX 0x00 | |
#define AX 0x00 | |
#define AH 0x01 | |
#define AL 0x00 | |
#define RBX 0x08 | |
#define EBX 0x08 | |
#define BX 0x08 | |
#define BH 0x09 | |
#define BL 0x08 | |
#define RCX 0x10 | |
#define ECX 0x10 | |
#define CX 0x10 | |
#define CH 0x11 | |
#define CL 0x10 | |
#define RDX 0x18 | |
#define EDX 0x18 | |
#define DX 0x18 | |
#define DH 0x19 | |
#define DL 0x18 | |
#define RSI 0x20 | |
#define ESI 0x20 | |
#define SI 0x20 | |
#define SIL 0x20 | |
#define RDI 0x28 | |
#define EDI 0x28 | |
#define DI 0x28 | |
#define DIL 0x28 | |
#define RBP 0x30 | |
#define EBP 0x30 | |
#define BP 0x30 | |
#define BPL 0x30 | |
#define RSP 0x38 | |
#define ESP 0x38 | |
#define SP 0x38 | |
#define SPL 0x38 | |
#define R8 0x40 | |
#define R8D 0x40 | |
#define R8W 0x40 | |
#define R8B 0x40 | |
#define R9 0x48 | |
#define R9D 0x48 | |
#define R9W 0x48 | |
#define R9B 0x48 | |
#define R10 0x50 | |
#define R10D 0x50 | |
#define R10W 0x50 | |
#define R10B 0x50 | |
#define R11 0x58 | |
#define R11D 0x58 | |
#define R11W 0x58 | |
#define R11B 0x58 | |
#define R12 0x60 | |
#define R12D 0x60 | |
#define R12W 0x60 | |
#define R12B 0x60 | |
#define R13 0x68 | |
#define R13D 0x68 | |
#define R13W 0x68 | |
#define R13B 0x68 | |
#define R14 0x70 | |
#define R14D 0x70 | |
#define R14W 0x70 | |
#define R14B 0x70 | |
#define R15 0x78 | |
#define R15D 0x78 | |
#define R15W 0x78 | |
#define R15B 0x78 | |
#define RFLAGS 0xf8 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <cstddef> | |
#include <cstdint> | |
#include <cstdbool> | |
#include <uchar.h> | |
// Check windows | |
#if _WIN32 || _WIN64 | |
#if _WIN64 | |
#define ENVIRONMENT64 | |
#else | |
#define ENVIRONMENT32 | |
#endif | |
#endif | |
// Check GCC | |
#if __GNUC__ | |
#if __x86_64__ || __ppc64__ | |
#define ENVIRONMENT64 | |
#else | |
#define ENVIRONMENT32 | |
#endif | |
#endif | |
#ifdef ENVIRONMENT64 | |
typedef int64_t Int; | |
typedef uint64_t Nat; | |
typedef int32_t HalfInt; | |
typedef uint32_t HalfNat; | |
#endif | |
#ifdef ENVIRONMENT32 | |
typedef int32_t Int; | |
typedef uint32_t Nat; | |
typedef int16_t HalfInt; | |
typedef uint16_t HalfNat; | |
#endif | |
typedef uint8_t Nat8; | |
typedef uint16_t Nat16; | |
typedef uint32_t Nat32; | |
typedef uint64_t Nat64; | |
typedef int8_t Int8; | |
typedef int16_t Int16; | |
typedef int32_t Int32; | |
typedef int64_t Int64; | |
typedef char Byte; | |
typedef char16_t Word; | |
typedef char32_t Char; | |
typedef size_t Index; | |
typedef intptr_t Address; | |
typedef void * Pointer; | |
typedef float Float; | |
typedef double Double; | |
typedef bool Bool; | |
typedef int TypeNum; | |
enum TYPENUM { | |
UNDEFINED = 0, | |
VOID, | |
NAT, | |
INT, | |
NAT8, | |
NAT16, | |
NAT32, | |
NAT64, | |
INT8, | |
INT16, | |
INT32, | |
INT64, | |
BYTE, | |
WORD, | |
CHAR, | |
INDEX, | |
ADDRESS, | |
POINTER, | |
FLOAT, | |
DOUBLE, | |
BOOL, | |
INVALID, | |
}; | |
enum Ord { LT = -1, EQ = 0, GT = 1 }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
レジスタの初期化いらないから消す