#include <math.h> #include <stdint.h> #include <stdio.h> #define MEMORY_SIZE 65536 // Helpful stuff (things that will probably be used to implement more than one instruction type) // struct representing a processor: struct ProcessorState { int32_t registers[17]; int32_t memory[MEMORY_SIZE]; }; // Reads bits from source in the range [start, end] (inclusive). Returns a uint32_t with the result as its least significant bits. // (e.g. getBits(8, 2, 3) == 2) int32_t getBits(int source, int start, int end) { return (source & ((2 << end) - (1 << start))) >> start; } // Shorthand for getBits(source, index, index) int isSet(int source, int index) { return (source & (1 << index)); } // Returns 1 if the condition code 'cond' is satisfied by the processor's current state, and 0 otherwise. // Any condition code not listed in the spec will cause this to return 0. int validCond(int32_t cond, struct ProcessorState *processor) { int32_t cprs = (*processor).registers[16]; int n = isSet(cprs, 31); int z = isSet(cprs, 30); int c = isSet(cprs, 29); int v = isSet(cprs, 28); switch (cond) { case 0: return z; case 1: return !z; case 10: return n == z; case 11: return n != z; case 12: return !z && (n == v); case 13: return z || (n != v); case 14: return 1; default: return 0; } } /* (not finished): int32_t barrelShift(int immediate, int32_t operand, int *carry, struct ProcessorState *processor) { if (immediate) { unsigned int rotate = (unsigned int)getBits(operand, 8, 11); uint32_t imm = (uint32_t)getBits(operand, 0, 7); return (imm >> (2 * rotate)) | (imm << (32 - 2 * rotate)); } uint32_t reg = (uint32_t)(*processor).registers[getBits(operand, 8, 11)]; unsigned int shift = getBits(operand, 5, 6); } */ // TODO: applyOperation(int opcode, int32_t operator1, int32_t operator2, int *carry)