// 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; }
// 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; } }
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; }
/** * Takes a FILE handle in as input (corresponding to * an encoded file) and reads the file, char by char. The * bit at the input index of each char is extracted (by calling * extractBit). The least significant bit is in index 0. * * For each character, if the extracted bit is 0, output ASCII '0' to * the output file. If the extracted bit is 1, output ASCII * '1' to the output file. * * @param in the input file handle to read from * @param out the output file to write the extracted ASCII binary into * @param index the index of the bit to extract from each char */ void codeToBinary(FILE *in, FILE *out, int index){ char tempchar; int bit; while(1) { tempchar=fgetc(in); if(tempchar==EOF) break; bit=extractBit(tempchar,index); printf("%d",bit); fputc(bit?'1':'0',out);//originally '0'-bit } }
// 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; }
// PRE: num is not 0 int getLastOnePos(uint32_t num) { assert(num != 0); for (int i = 0; i < INTWIDTH; ++i) { if (extractBit(num, i)) { return i; } } fprintf(stderr, "Error in tokenHandlers: getLastOnePos: Invalid num %u", num); exit(EXIT_FAILURE); }
/** * Takes a FILE handle in as input (corresponding to * an encoded file) and reads the file, char by char. The * bit at the input index of each char is extracted (by calling * extractBit). The least significant bit is in index 0. * * For each character, if the extracted bit is 0, output ASCII '0' to * the output file. If the extracted bit is 1, output ASCII * '1' to the output file. * * @param in the input file handle to read from * @param out the output file to write the extracted ASCII binary into * @param index the index of the bit to extract from each char */ void codeToBinary(FILE *in, FILE *out, int index){ //if in file or out file are null, end the function if(in == NULL || out == NULL) return; while(1) { //get the char in file in char temp = fgetc(in); //if reach the end of file, break if(feof(in)) { break; } //write the output to the out file //'0' is the offset fprintf(out, "%c", extractBit(temp, index)+'0'); } }
int writeData(fitsfile *fp,FILE *fout,dSet *data,long s1,long s2,float dm) { long sub_1,samp_1; long sub_2,samp_2; int s,r1,r2; int nsblk; int nchan = data->phead.nchan; int nbits = data->phead.nbits; int npol = data->phead.npol; int samplesperbyte = 8/data->phead.nbits; float chanVal[nchan]; long ipos=0; int status=0; int colnum; int initflag=0; unsigned char *cval; unsigned char nval = '0'; int i,c,count=0,sa; unsigned char chVals[nchan]; int smoothSamp=1; int sm; unsigned int t=0; unsigned int j; float tempVal; int nsampDM; float tDM; float bw = data->phead.bw; // MHz float f0 = data->phead.freq+fabs(data->phead.bw)/2.0; // MHz // Highest frequency float chanbw = data->phead.bw/data->phead.nchan; unsigned char *ring_s; unsigned char *ring_e; unsigned char *ring_pos; unsigned char *ring_last; unsigned int bitCount; int cdelay,k,l; float tdelay; unsigned int pos; unsigned int **cde_byte; unsigned char **cde_bit; unsigned int nchanbyte; nchanbyte = nchan/samplesperbyte; // Do we require smoothing? printf("At here: smoothSamp = %d\n",smoothSamp); nsblk = data->phead.nsblk; findPosSample(data,s1,&sub_1,&samp_1); findPosSample(data,s2,&sub_2,&samp_2); // printf("Here with %d %d %d %d\n",sub_1,samp_1,sub_2,samp_2); // Go to the subint table fits_movnam_hdu(fp,BINARY_TBL,"SUBINT",1,&status); if (status) { printf("Unable to move to subint table in FITS file\n"); exit(1); } fits_get_colnum(fp,CASEINSEN,"DATA",&colnum,&status); if (status) { printf("Unable to find data in the subint table in FITS file\n"); exit(1); } // Number of extra samples required to process // to de-disperse across the band tDM = fabs(4.15e-3*dm*(pow((f0)/1000.0,-2)-pow((f0-fabs(bw))/1000.0,-2))); nsampDM = ceil(tDM/data->phead.tsamp); cval = (unsigned char *)malloc(sizeof(unsigned char)*nchanbyte*npol*nsampDM); printf("Trying to allocate memory\n"); cde_byte = (unsigned int **)malloc(sizeof(unsigned int *)*nsampDM); cde_bit = (unsigned char **)malloc(sizeof(unsigned char *)*nsampDM); for (i=0;i<nsampDM;i++) { cde_byte[i] = (unsigned int *)malloc(sizeof(unsigned int)*nchan*npol*nsampDM); cde_bit[i] = (unsigned char *)malloc(sizeof(unsigned char)*nchan*npol*nsampDM); } printf("Allocated memory\n"); // Now turn on the bits that correspond to the DM j=0; for (i=0;i<nchan;i++) { tdelay = 4.15e-3*dm*(pow(f0/1000.0,-2)-pow((f0-fabs(chanbw)*i)/1000.0,-2)); cdelay = nint(-tdelay/data->phead.tsamp); // printf("Have %g %d\n",tdelay,cdelay); for (j=0;j<nsampDM;j++) { k = (int)((float)i/(float)samplesperbyte)+cdelay*nchanbyte+j*nchan/samplesperbyte; if (k>(nsampDM)*nchanbyte) k-=nsampDM*nchanbyte; if (k>(nsampDM)*nchanbyte) { printf("ERROR\n"); exit(1); } cde_byte[j][i] = k; cde_bit[j][i] = i%8; } } printf("Ready\n"); ring_s = cval; ring_pos = cval; ring_e = &cval[nchanbyte*npol*(nsampDM)]; printf("Got here 2\n"); // Should check if I'm running off the end of a subint s = sub_1; sa = samp_1; // Use a ring buffer to store the data // Fill it up count = 0; t=0; pos = 0; printf("Got here 3\n"); fprintf(fout,"# %s %d %g %g\n",data->phead.source,data->phead.imjd,data->phead.freq,data->phead.tsamp); for (i=0;i<s2-s1-nsampDM;i++) { // printf("i = %d, s = %d, sa = %d\n",i,s,sa); fits_read_col_byt(fp,colnum,s+1,(sa)*nchanbyte+1,nchanbyte,nval,ring_pos,&initflag,&status); sa++; if (i >= nsampDM-1) { bitCount = 0; // for (k=0;k<35;k++) { for (j=0;j<nchan;j++) { // bitCount += extractBit(cval[cde_byte[t][j]],cde_bit[t][j]); // ONLY 1-BIT DATA bitCount += extractBit(cval[cde_byte[t][j]],j%8); // bitCount+=cde_byte[t][j]+cde_bit[t][j]; } } fprintf(fout,"%d\n",bitCount); t++; } ring_pos += nchanbyte*npol; if (ring_pos == ring_e) { // printf("Got to end of ring buffer %d %d\n",i,nsampDM); ring_pos = ring_s; t=0; } if (sa == nsblk) { // printf("Running off the end of a block\n"); s++; sa = 0; } } tempVal=0; // printf("Got here\n"); // exit(1); if (status) { fits_report_error(stderr,status); exit(1); } // printf("Complete %d %d\n",t,count); free(cval); for (i=0;i<nsampDM;i++) { free(cde_byte[i]); free(cde_bit[i]); } free(cde_byte); free(cde_bit); return count; }
// So, first, let us write a function to update a particular bit of A and E depending on M. n - step number int updateBit (int bitPos, int step, unsigned int A[], unsigned int E[], unsigned int m[], char mChar[][32], char aChar[][32], char eChar[][32]) { // Let us build the bitPos - bit of A and E. int bitE, bitA, bitEC, bitAC; int chBit1 = extractBit(E, step - 1, bitPos); int chBit2 = extractBit(E, step - 2, bitPos); int chBit3 = extractBit(E, step - 3, bitPos); int chBit = ch(chBit1, chBit2, chBit3); int constBit = extractBit(k, step, bitPos); int wordBit = extractBit(m, step, bitPos); int EBit_4 = extractBit(E, step - 4, bitPos); int ABit_4 = extractBit(A, step - 4, bitPos); int sBit1 = extractBit(E, step - 1, (bitPos - 6) % 32); int sBit2 = extractBit(E, step - 1, (bitPos - 11) % 32); int sBit3 = extractBit(E, step - 1, (bitPos - 25) % 32); int sBit = sBit1 ^ sBit2 ^ sBit3; int bitECarry = extractBit(ECarry, step, bitPos-1); int bitE = EBit_4 ^ sBit ^ chBit ^ ABit_4 ^ constBit ^ wordBit ^ bitECarry; int bitEC = (EBit_4 + sBit + chBit + ABit_4 + constBit + wordBit + bitECarry) >> 1; // Dropped the last bit to generate the carry. int SBit1 = extractBit(A, step - 1, (bitPos - 2) % 32); int SBit2 = extractBit(A, step - 1, (bitPos - 13) % 32); int SBit3 = extractBit(A, step - 1, (bitPost - 22) % 32); int SBit = SBit1 ^ SBit2 ^ SBit3; int bitACarry = extractBit(ACarry, step, bitPos - 1); int mjBit1 = extractBit(A, step - 1, bitPos); int mjBit2 = extractBit(A, step - 2, bitPos); int mjBit3 = extractBit(A, step - 3, bitPos); int mjBit = mj(mjBit1, mjBit2, mjBit3); int bitA = (-ABit_4) ^ SBit ^ bitE ^ mjBit; int bitACarry = ((-ABit_4) + SBit + bitE + mjBit) >> 1; }
int main() { word16 x=1111; // nombre entre 1000 et 9999 pour Von Neumann struct mt19937p mt; // Pour Mersenne-Twister int tmp = rand(); // Pour Mersenne-Twister u32 Kx[NK], Kex[NB*NR], Px[NB]; // pour l'AES int n = 1024; // Echantillon de test int * output_rand = malloc(sizeof(int)*n); // sortie du rand du C int ** output_rand_fort = malloc(sizeof(sizeof(int)*4)*n); // sortie du rand du C (4 bits poids fort) int ** output_rand_faible = malloc(sizeof(sizeof(int)*4)*n); // sortie du rand du C (4 bits poids faible) word32 * output_AES = malloc(sizeof(word32)*n); // sortie pour l'AES word16 * output_VN = malloc(sizeof(word16)*n); // sortie pour pour Von Neumann word32 * output_MT = malloc(sizeof(word32)*n); // sortie pour Mersenne-Twister // initialisation des graines des generateurs srand(rdtsc()); // rand du C sgenrand(time(NULL)+(tmp), &mt); // Mersenne-Twister // Initialisation de la clé et du plaintext pour l'AES // 45 est un paramètre qui doit changer à chaque initialisation init_rand(Kx, Px, NK, NB, 45); KeyExpansion(Kex,Kx); // AES : sous-clefs for(int i = 0; i < n; i++) { // sorties des generateurs output_rand[i] = rand(); // rand du C int* tempBin = convertBin(output_rand[i], taille_int); output_rand_fort[i] = extractBit(tempBin, 1, taille_int); output_rand_faible[i] = extractBit(tempBin, 0, taille_int); for(int j = 0; j < 4; j++) { if(!(tempBin[taille_int-1-j] == output_rand_faible[3-j])) { printf("PAS OK !!!!"); } } output_VN[i] = Von_Neumann(&x); // Von Neumann output_MT[i] = genrand(&mt); // Mersenne-Twister output_AES[i] = AES(Px, Kex); // AES } // affichage /*printf("- Generation de nombres aleatoires -\n"); printf("rand du C (poids fort) :\n"); for(int i = 0; i < n; i++) { checkBin(output_rand_fort[i], 4); } /*printf("rand du C (poids faible) :\n"); for(int i = 0; i < n; i++) { displayBinToDec(output_rand_faible[i],4); } printf("Von Neumann : \n"); displayValuesWord16(output_VN, n); printf("Mersenne Twister : \n"); displayValuesWord32(output_MT, n); printf("AES : \n"); displayValuesWord32(output_AES, n); */ // tests double testFreq_randFort = Frequency(output_rand_fort, n, 4); //double testFreq_randFaible = Frequency(output_rand_faible, n, 4); /*double testFreq_aes = Frequency(makeArrayWord32(output_AES,n), n, 32); double testFreq_VN = Frequency(makeArrayWord16(output_VN,n), n, 16); double testFreq_MT = Frequency(makeArrayWord32(output_MT,n), n, 32); printf("PValeurs : \n \ Rand Bits Poids Fort : %lf\n \ Rand Bits Poids Faible : %lf\n \ AES : %lf\n \ VN : %lf\n \ MT : %lf\n",testFreq_randFort,testFreq_randFaible,testFreq_aes,testFreq_VN,testFreq_MT);*/ return 0; }