#include "vm.h" #include #include #include #include #include #include #include #include #include #include namespace wg_asm { /* push (val) //( -- val) pop (dest) //(a -- ) a -> (dest) peek (dest) //(a -- a) a -> (dest) //Gets one value from the input and pushes it input //Rotates top (n) values on the stack by (p) places rot (n) (p) //rot 3 2: //(a b c -- b c a) //Reverses top (n) stack values reverse (n) //reverse 3: //(a b c -- c b a) //Duplicates the top of the stack without using a register dup //(a -- a a) //Equivalent to push (val); pop (dest) set (dest) (val) //Stack-based math abs //(a -- abs(a)) add //(a b -- a+b) sub mul idiv //FP "coprocessor" control: //based on value of [func], performs a complex floating point operation on the values in the stack fmath //Stack-based bitwise bitand bitor bitxor bitnot //Split top of stack into (n) (power of two in range 2-64) segments, big-endian, data in low bits explode#n //Join together top (n) (same as above) words' low bits into one word collapse#n //Stack-based logic and or xor //Stack-based comparisons (result in [flag]) cmpgt cmpge cmpeq //Pops top of stack and converts to bool, result in [flag] bool //inverts [flag] not //Execution jump: //Calls function in [func] //Number of arguments passed on stack in [arg] //Return values on stack, number returned in [arg] transfer //Unconditional jump to [jump] jmp //Jumps to [jump] only if [flag] is true ifjmp //Execution returns to just after the last transfer return //If [flag] is false, then exit with message (error) assert (error) */ /* [stackptr] "Address of the top of the stack" [codeptr] "Execution address" [jump] "Destination of jmp/ifjmp" [func] "Function that will be called by transfer" [counter] "Program controlled register. Conventionally holds old [stackptr] values" [arg] "Program controlled register. See documentation of transfer." [flag] "Set by comparison and boolean instructions, checked by conditionals" [gp0] [gp1] "General-purpose registers" [zero] "always contains 0, even when assigned to" [one] "always holds 1" [max] "always holds -1ull" //hidden: [IN] [OUT] "serial devices" //memory mapped: [r#0] [r#1] ... [r#[r#c]] "Input arguments" [r#d] [r#D] [r#c] [r#C] [r#a] [r#A] [...] "Special arguments" */ std::pair> mnemonic_to_opcode(std::string_view s) { //Structure of an instruction: //64 bits total //16: opcode // 1: cond // 1: indirection2 // 6: addr2 //20: immediate data //20: immediate data //Addressing modes for addr2: //0: no operand //1: stack //2: small immediate (limited to 20 bits) //3: immediate (following word) //4: memory-mapped register //5-15: unused //16-63: register } //Expand all macros in source std::string pass_macro(const std::string& prog); //Exract all symbols and strings used std::pair, std::vector> pass_extract(const std::string& prog); //Substitute symbols for strings std::string pass_symbol(const std::string& prog); // std::vector assemble(const std::string& prog) { return {}; } } wg_asm::i64 g() { wg_asm::i64 v; std::cin>>std::hex>>v; return v; } wg_asm::instruction h(wg_asm::instruction* i) { return *i; } int main() { auto v = g(); wg_asm::instruction a[2] {v, wg_asm::word_cast(v)}; // for (auto& j : a) { // auto i = h(&j); // std::printf("%c%c%c%c%c%c%c%c%c%c", // (int)sizeof(i), // i.opcode, // i.cond, i.indirect2,i.addr2, // i.immediate1, i.immediate2 // ); // } std::cout<(a[0])<<'\n'; if (a[0] != wg_asm::word_cast(v)) { std::cout<<"a[0] != word_cast(v)\n"; } std::cout<(a[1])<<'\n'; if (a[1] != wg_asm::word_cast(v)) { std::cout<<"a[1] != word_cast(v)\n"; } // assert(instruction(264676437ll) == instruction(word_cast(264676437ll))); }