#pragma once #include "instructions/instructions.h" #include "instructions/registers.h" #define readVar(VAR) {\ if(!VM_dataRead(vm, &VAR, vm->current_pos, sizeof(VAR))) \ return -1;\ vm->current_pos += sizeof(VAR);\ } #define validateRegisterCode(VAR) \ if(VAR == RegisterCode_Unset || VAR > RegisterCode_dh){\ VM_setError(vm, "invalid register index (%x)", VAR);\ return -1;\ } #define readRegisterCode(VAR) {\ readVar(VAR);\ validateRegisterCode(VAR);\ } #define OPERATOR_IMPL_1(NAME, OPERATOR)\ i32 NAME##_impl (VM* vm) {\ RegisterCode dst_reg_code = 0;\ readRegisterCode(dst_reg_code);\ u64 dst_reg_value = 0;\ VM_registerRead(vm, &dst_reg_value, dst_reg_code);\ \ dst_reg_value = OPERATOR dst_reg_value;\ VM_registerWrite(vm, &dst_reg_value, dst_reg_code);\ return sizeof(dst_reg_code);\ } #define OPERATOR_IMPL_2(NAME, OPERATOR)\ i32 NAME##_impl (VM* vm) {\ RegisterCode dst_reg_code = 0, src_reg_code = 0;\ readRegisterCode(dst_reg_code);\ readRegisterCode(src_reg_code);\ u64 dst_reg_value = 0, src_reg_value = 0;\ VM_registerRead(vm, &dst_reg_value, dst_reg_code);\ VM_registerRead(vm, &src_reg_value, src_reg_code);\ \ dst_reg_value = dst_reg_value OPERATOR src_reg_value;\ VM_registerWrite(vm, &dst_reg_value, dst_reg_code);\ return sizeof(dst_reg_code) + sizeof(src_reg_code);\ } #define OPERATOR_IMPL_CMP_FLAG(NAME, OPERATOR)\ i32 NAME##_impl (VM* vm) {\ RegisterCode src0_reg_code = 0, src1_reg_code = 0;\ readRegisterCode(src0_reg_code);\ readRegisterCode(src1_reg_code);\ u64 src0_reg_value = 0, src1_reg_value = 0;\ VM_registerRead(vm, &src0_reg_value, src0_reg_code);\ VM_registerRead(vm, &src1_reg_value, src1_reg_code);\ \ vm->flags.cmp = src0_reg_value OPERATOR src1_reg_value;\ return sizeof(src0_reg_code) + sizeof(src1_reg_code);\ }