void interpretPop(Instruction* ins) { switch(ins->argSize) { case 1: popByte(); break; case 2: popWord(); break; case 4: popDword(); break; case 8: popQword(); break; } }
void interpretConv(Instruction* ins) { switch(ins->opcode) { case CONVB_D: pushDword((uint32_t)popByte()); break; case CONVD_B: pushByte((uint8_t)popDword()); break; case CONVD_W: pushWord((uint16_t)popDword()); break; case CONVQ_D: pushQword((uint64_t)popDword()); break; case CONVD_Q: pushDword((uint32_t)popQword()); break; } }
void interpretStelem_b(Instruction* ins) { writeByte(popDword() + popDword(), popByte()); }
// Arbitrary-size pop function unsigned int popFromBuffer(buffer_t *b, void *d, unsigned int l){ unsigned int elementIndex, byteIndex; for (elementIndex = 0; elementIndex < l; elementIndex++) { for (byteIndex = 0; byteIndex < b->width; byteIndex++) { if (!isBufferEmpty(b)){ // Stacks swap bytes of multi-byte elements, so swap back // on pop operation if (b->behavior.bits.stack){ *( (unsigned char*)(d + ((elementIndex + 1) * b->width) - 1 - byteIndex) ) = popByte(b); } // Queue does not swap bytes, so no need to swap on pop else { *( (unsigned char*)(d + (elementIndex * b->width) + byteIndex) ) = popByte(b); } } else { // Push any bytes back to buffer that form an incomplete element // -Ideally this should never run, but added just in case unsigned int failedbytes; for (failedbytes=byteIndex; failedbytes > 0; failedbytes--){ // Careful not to swap bytes here... pushByte(b, *( (unsigned char*)(d + elementIndex * b->width + failedbytes ) )); } // Return a count of failed pop operations // -Include partial pops in counter return l - elementIndex; } } } return 0; }
// popWord() - Pops a word using popByte() twice int popWord() { return popByte() + (popByte() << 8); }
void popBytes(char *buffer, int bytes) { for(int i = 0; i < bytes; ++i) buffer[i] = popByte(); }