int decode(machine_t *m, uint32_t instr) { int code = extractBits(instr, 27, 2); //if (condCheck(m, instr)) { switch (code) { case 1: //sdt(m,instr); return 1; case 2: //branch(m,instr); return 2; } int multCheck1 = extractBits(instr, 7, 4); int multCheck2 = extractBits(instr, 27, 6); if (multCheck1 == bitPattern1001 && multCheck2 == 0) { //multiply(m, instr); return 3; } else { //dataProc(m, instr); return 4; } fprintf(stderr, "ERROR: Bad instruction.\n"); return 5; //} }
// PRE: instr is a data process instruction // assume: PC does not feature in the instruction // behavior: checks opcode and performs instruction, possibly writes result to register and updates flags void dataProcess(uint32_t instr) { bool I = extractBit(instr, IMM_BIT); uint32_t opcode = extractFragmentedBits(instr, OPCODE_UPPER, OPCODE_LOWER); bool S = extractBit(instr, S_BIT); uint32_t RnVal = REGFILE[extractBits(instr, Rn_UPPER, Rn_LOWER)]; uint32_t Rd = extractBits(instr, Rd_UPPER, Rd_LOWER); ShiftResult operand2WC = getOperand2(instr, I); uint32_t operand2 = operand2WC.result; bool C = operand2WC.carry; bool writeResult = true; uint32_t result = 0; switch (opcode) { case tst: writeResult = false; case and: result = RnVal & operand2; break; case teq: writeResult = false; case eor: result = RnVal ^ operand2; break; case cmp: writeResult = false; case sub: result = RnVal - operand2; C = RnVal >= operand2; break; case rsb: result = operand2 - RnVal; C = operand2 >= RnVal; break; case add: result = RnVal + operand2; C = extractBit(RnVal, MSB) && extractBit(operand2, MSB); break; case orr: result = RnVal | operand2; break; case mov: result = operand2; break; default: fprintf(stderr, "invalid opcode in dataProcess: opcode was %d " "(0x%08x)\n", opcode, opcode); exit(EXIT_FAILURE); } if (S) { updateCPSR(C, Cbit); updateCPSR(!result, Zbit); updateCPSR(extractBit(result, Nbit), Nbit); } if (writeResult) { REGFILE[Rd] = result; } }
void emulatorEmitScreenshot() { int file; if (RUNNING_ON_EMULATOR) { sceIoDevctl("kemulator:", EMULATOR_DEVCTL__EMIT_SCREENSHOT, NULL, 0, NULL, 0); } else { uint topaddr; int bufferwidth; int pixelformat; sceDisplayGetFrameBuf((void **)&topaddr, &bufferwidth, &pixelformat, 0); if (topaddr & 0x80000000) { topaddr |= 0xA0000000; } else { topaddr |= 0x40000000; } if ((file = sceIoOpen("__screenshot.bmp", PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC, 0777)) >= 0) { int y, x; uint c; uint* vram_row; uint* row_buf = (uint *)malloc(512 * 4); sceIoWrite(file, &bmpHeader, sizeof(bmpHeader)); for (y = 0; y < 272; y++) { vram_row = (uint *)(topaddr + 512 * 4 * (271 - y)); for (x = 0; x < 512; x++) { c = vram_row[x]; /* row_buf[x] = ( ((extractBits(c, 0, 8)) << 0) | ((extractBits(c, 8, 8)) << 8) | ((extractBits(c, 16, 8)) << 16) | (( 0x00 ) << 24) | 0); */ row_buf[x] = ( ((extractBits(c, 16, 8)) << 0) | ((extractBits(c, 8, 8)) << 8) | ((extractBits(c, 0, 8)) << 16) | (( 0x00 ) << 24) | 0); } sceIoWrite(file, row_buf, 512 * 4); } free(row_buf); //sceIoWrite(file, (void *)topaddr, bufferwidth * 272 * 4); //sceIoFlush(); sceIoClose(file); } } }
// PRE: instr is not the halt instruction // Behaviour: Decides which of the 4 instruction types instr is and passes it to its subsequent function // i.e. branch(instr), dataTransfer(instr) etc. bool decodeAndExecute(uint32_t instr) { bool isBranch = extractBit(instr, bit27); bool isDataTransfer = extractBit(instr, bit26); bool mulCheck = extractBit(instr, bit25); uint32_t pattern = extractBits(instr, PATTERN_UPPER, PATTERN_LOWER); if (isBranch) { // puts("Executing branch instruction\n"); branch(instr); return true; } else if (isDataTransfer) { // puts("Executing data transfer instruction\n"); dataTransfer(instr); } else if (!mulCheck && pattern == MUL_PATTERN) { // puts("Executing multiplier instruction\n"); iMultiply(instr); } else { // puts("Executing data process instruction\n"); dataProcess(instr); } return false; }
void testExtractBits(void){ printf("----------------------TESTING EXTRACTBITS------------------------\n"); uint32_t ret1 = extractBits(100, 3, 3); uint32_t ret2 = extractBits(0, 2, 2); uint32_t ret3 = extractBits(285253859, 27, 2); uint32_t ret4 = extractBits(570458412, 27, 2); uint32_t expe1 = 2; uint32_t expe2 = 0; uint32_t expe3 = 0; uint32_t expe4 = 0; if(!(ret1 == expe1 && ret2 == expe2 && ret3 == expe3 && ret4 == expe4)){ printf("ret1 = %i : expected : %i\n", ret1, expe1); printf("ret2 = %i : expected : %i\n", ret2, expe2); printf("ret3 = %i : expected : %i\n", ret3, expe3); printf("ret4 = %i : expected : %i\n", ret4, expe4); } }
int signedExtension(uint16_t numToExtendBy, uint32_t instrToExtend) { int startBit = 32 - numToExtendBy; int mask = maskMaker(numToExtendBy) << startBit; int extractedBit = extractBits(instrToExtend, startBit, 1); if (extractedBit == 1) { instrToExtend = instrToExtend | mask; } return instrToExtend; }
uint32_t calcOffset(Assembler *assembler, uint32_t address, bool reduce) { uint32_t offset = address - (assembler->currInstrAddr + PIPELINE_LENGTH); if (!reduce) { return offset; } uint32_t reducedOffset = extractBits(offset, 24, 0) | extractBit(offset, 31) << 25; return binaryShift(reducedOffset, LSR, 2).result; }
/*Find the bit-sync codes in the pcmBits array, and extract the frames.*/ void JRS_PCM_sync(JRS_PCM *p) { /*Find the bit offset to the frame start (search over two frame's worth)*/ int bitOffset; for (bitOffset=0;bitOffset<8*256;bitOffset++) { static const unsigned char frameSync[3]={0xFA,0xF3,0x20}; unsigned char curSync[3]; extractBits(p->pcmBits,bitOffset,3,curSync); if ((frameSync[0]==curSync[0])&&(frameSync[1]==curSync[1])&&(frameSync[2]==curSync[2])) break;/*Jump out of loop*/ } p->startBit=bitOffset; /*Now that we've found the bit synchronization code, extract each frame, bit-aligned.*/ for (p->nFrames=0;(bitOffset+(p->nFrames+1)*8*128)<p->nBits;p->nFrames++) extractBits(p->pcmBits,bitOffset+p->nFrames*8*128,128,&p->frames[p->nFrames*128]); }
// PRE: instr is a multiply instruction and in big endian // behavior: multiplication instruction as in spec void iMultiply(uint32_t instr) { uint32_t Rd = extractBits(instr, Rd_MUL_UPPER, Rd_MUL_LOWER); uint32_t RsVal = REGFILE[extractBits(instr, Rs_UPPER, Rs_LOWER)]; uint32_t RmVal = REGFILE[extractBits(instr, Rm_UPPER, Rm_LOWER)]; bool Abit = extractBit(instr, A_BIT); bool Sbit = extractBit(instr, S_BIT); uint32_t acc = 0; uint32_t result; if (Abit) { acc = REGFILE[extractBits(instr, Rn_MUL_UPPER, Rn_MUL_LOWER)]; } result = RmVal * RsVal + acc; if (Sbit) { //Nbit = bit 31 of result updateCPSR(extractBit(result, Nbit), Nbit); updateCPSR(result != 0, Zbit); } REGFILE[Rd] = result; }
unsigned int hashFunction(int index0, int index1) { //return concat(extractBits(index0, 0, 1), extractBits(index1, 0, 4)); return extractBits(index0, 0, 1) | extractBits(index1, 0, 14); }
unsigned int hashFunction(int index0, int index1) { return concat(extractBits(index0, 0, 3), extractBits(index1, 0, 7)); //return extractBits(index0, 0, 3) | extractBits(index1, 0, 4); }
/* * Read input from FILE pointer fp and return a new in memory representation * of the input. */ pbm_t* pbm_read(FILE* fp) { pbm_t* pbm = (pbm_t*)malloc(sizeof(pbm_t)); if (!pbm) { char errorMsg[CHAR_BUF]; sprintf(errorMsg, "Error allocating struct pbm."); perror(errorMsg); exit(-1); } char magicNum[CHAR_BUF]; char sWidth[CHAR_BUF]; char sHeight[CHAR_BUF]; memset(pbm, '\0', sizeof(pbm_t)); memset(magicNum, '\0', CHAR_BUF * sizeof(char)); memset(sWidth, '\0', CHAR_BUF * sizeof(char)); memset(sHeight, '\0', CHAR_BUF * sizeof(char)); uint8_t c; int i = 0; int nWidth = 0; int nHeight = 0; /* read magic num */ while (!isspace((c = fgetc(fp)))) { magicNum[i++] = c; if (i >= CHAR_BUF) { fprintf(stderr, "Woops! Can't handle input size\n"); exit(-1); } } magicNum[i] = '\0'; /* make sure magicNum = P4 */ if (strcmp("P4", magicNum) != 0) { fprintf(stderr, "Error: invalid PBM file format\n"); exit(-1); } /* burn whitespace */ while (isspace((c = fgetc(fp)))); /* reset */ i = 0; sWidth[i++] = c; /* read width */ while (!isspace((c = fgetc(fp)))) { sWidth[i++] = c; if (i >= CHAR_BUF) { fprintf(stderr, "Woops! Can't handle input size\n"); exit(-1); } } sWidth[i] = '\0'; if ((nWidth = atoi(sWidth)) == 0) { fprintf(stderr, "Error: invalid PBM file format\n"); exit(-1); } /* burn whitespace */ while (isspace((c = fgetc(fp)))); /* reset */ i = 0; sHeight[i++] = c; /* read height */ while (!isspace((c = fgetc(fp)))) { sHeight[i++] = c; if (i >= CHAR_BUF) { fprintf(stderr, "Woops! Can't handle input size\n"); exit(-1); } } sHeight[i] = '\0'; if ((nHeight = atoi(sHeight)) == 0) { fprintf(stderr, "Error: invalid PBM file format\n"); exit(-1); } pbm->width = nWidth; pbm->height = nHeight; /* input is 8 packed bits per byte w/ zeroed don't care bits */ int bytesPerRow = 0; if (pbm->width % 8 == 0) { bytesPerRow = pbm->width / 8; } else { bytesPerRow = pbm->width / 8 + 1; } pbm->size = bytesPerRow * 8 * pbm->height; pbm->pad = bytesPerRow * 8 - pbm->width; pbm->buf = malloc(pbm->size); if (!pbm->buf) { char errorMsg[CHAR_BUF]; sprintf(errorMsg, "Error allocating pbm->buf."); perror(errorMsg); exit(-1); } memset(pbm->buf, 0, pbm->size); int nObj = 0; int pos = 0; int col = 0; while (!feof(fp)) { nObj = fread(&c, 1, 1, fp); if (nObj) { extractBits(c, &pos, &col, pbm); } } return pbm; }