void cbc_decipher(const unsigned char *ciphertext, unsigned char *plaintext, const unsigned char *key, int size) { unsigned char temp[8]; int i; /***************************************************************************** * * * Decipher the initialization vector. * * * *****************************************************************************/ des_decipher(&ciphertext[0], &plaintext[0], key); /***************************************************************************** * * * Decipher the buffer using DES in CBC mode. * * * *****************************************************************************/ i = 8; while (i < size) { des_decipher(&ciphertext[i], temp, NULL); bit_xor(&ciphertext[i - 8], temp, &plaintext[i], 64); i = i + 8; } return; }
void des(INT32 encry_flag,UCHAR *key,UCHAR *data,UCHAR *edata) { INT32 i, j; UCHAR tmp_bit[64]; spilt_bit(key,8,key_bit); spilt_bit(data,8,data_bit); key_calculation(key_bit); for (i=0;i<32;i++) { /* initial permutate */ data_lbit[i] = data_bit[des_ip[i]-1]; data_rbit[i] = data_bit[des_ip[i+32]-1]; } switch (encry_flag) { case 1: /* encry data */ for (i=0;i<16;i++) { /* L' = R, R' = L xor f(R,Kn) */ for (j=0;j<32;j++) tmp_bit[j] = data_rbit[j]; f_cipher(data_rbit,key_k[i],frk_bit); bit_xor(data_lbit,frk_bit,32,data_rbit); for (j=0;j<32;j++) data_lbit[j] = tmp_bit[j]; } break; default: /* decry data */ for (i=15;i>=0;i--) { /* L' = R, R' = L xor f(R,Kn) */ for (j=0;j<32;j++) tmp_bit[j] = data_rbit[j]; f_cipher(data_rbit,key_k[i],frk_bit); bit_xor(data_lbit,frk_bit,32,data_rbit); for (j=0;j<32;j++) data_lbit[j] = tmp_bit[j]; } break; } for (i=0;i<32;i++) { tmp_bit[i] = data_rbit[i]; tmp_bit[i+32] = data_lbit[i]; } for (i=0;i<64;i++) /* inverse initial perm */ data_bit[i] = tmp_bit[des_rip[i]-1]; merge_bit(data_bit,8,edata); }
int main() { int pos, size = CHAR_BIT; unsigned char bits1[] = "1"; unsigned char bits2[] = "0"; unsigned char bits3[] = "10"; unsigned char bitsx[CHAR_BIT]; printf("bits in char = %d\n\n", CHAR_BIT * sizeof(char)); printf("bits1 = \"%s\" = ", bits1); for (pos = 0; pos < CHAR_BIT; pos++) printf("%d", bit_get(bits1, pos)); bit_set(bits1, 6, 1); printf("\n\nAfter setting seventh bit to 1:\nbits1 = \"%s\" = ", bits1); for (pos = 0; pos < CHAR_BIT; pos++) printf("%d", bit_get(bits1, pos)); bit_xor(bits1, bits2, bitsx, CHAR_BIT); printf("\n\n\"%s\" XOR \"%s\" = ", bits1, bits2); for (pos = 0; pos < CHAR_BIT; pos++) printf("%d", bit_get(bitsx, pos)); printf("\n\nbits3 = \"%s\" = ", bits3); for (pos = 0; pos < CHAR_BIT * 2; pos++) { if ((pos % 4) == 0) printf(" "); printf("%d", bit_get(bits3, pos)); } bit_rot_left(bits3, CHAR_BIT * 2, 3); printf("\nbit_rot_left(bits3, %d, %d) = ", CHAR_BIT * 2, 3); for (pos = 0; pos < CHAR_BIT * 2; pos++) { if ((pos % 4) == 0) printf(" "); printf("%d", bit_get(bits3, pos)); } return 0; }
void f_cipher(UCHAR *r,UCHAR *k,UCHAR *frk) { UCHAR row,col; INT32 i,j; UCHAR tmp_bit[64]; UCHAR tmp[8]; for (i=0;i<48;i++) /* E bit-selection */ er[i] = r[des_e[i]-1]; bit_xor(er,k,48,tmp_bit); for (i=0;i<8;i++) { for (j=0;j<6;j++) key_b[j] = tmp_bit[i*6+j]; row = key_b[0] *2 + key_b[5]; col = key_b[1] *8 + key_b[2] *4 + key_b[3] *2 + key_b[4]; key_sb[i] = des_s[i][row][col]; } for (i=0;i<4;i++) tmp[i] = key_sb[i*2] * 16 + key_sb[i*2+1]; spilt_bit(tmp,4,tmp_bit); for (i=0;i<32;i++) /* primitive function P */ frk[i] = tmp_bit[des_p[i]-1]; }
static int des_main(const unsigned char *source, unsigned char *target, const unsigned char *key, DesEorD direction) { static unsigned char subkeys[16][7]; unsigned char temp[8], lkey[4], rkey[4], lblk[6], rblk[6], fblk[6], xblk[6], sblk; int row, col, i, j, k, p; /***************************************************************************** * * * If key is NULL, use the subkeys as computed in a previous call. * * * *****************************************************************************/ if (key != NULL) { /************************************************************************** * * * Make a local copy of the key. * * * **************************************************************************/ memcpy(temp, key, 8); /************************************************************************** * * * Permute and compress the key into 56 bits. * * * **************************************************************************/ permute(temp, DesTransform, 56); /************************************************************************** * * * Split the key into two 28-bit blocks. * * * **************************************************************************/ memset(lkey, 0, 4); memset(rkey, 0, 4); for (j = 0; j < 28; j++) bit_set(lkey, j, bit_get(temp, j)); for (j = 0; j < 28; j++) bit_set(rkey, j, bit_get(temp, j + 28)); /************************************************************************** * * * Compute the subkeys for each round. * * * **************************************************************************/ for (i = 0; i < 16; i++) { /*********************************************************************** * * * Rotate each block according to its round. * * * ***********************************************************************/ bit_rot_left(lkey, 28, DesRotations[i]); bit_rot_left(rkey, 28, DesRotations[i]); /*********************************************************************** * * * Concatenate the blocks into a single subkey. * * * ***********************************************************************/ for (j = 0; j < 28; j++) bit_set(subkeys[i], j, bit_get(lkey, j)); for (j = 0; j < 28; j++) bit_set(subkeys[i], j + 28, bit_get(rkey, j)); /*********************************************************************** * * * Do the permuted choice permutation. * * * ***********************************************************************/ permute(subkeys[i], DesPermuted, 48); } } /***************************************************************************** * * * Make a local copy of the source text. * * * *****************************************************************************/ memcpy(temp, source, 8); /***************************************************************************** * * * Do the initial permutation. * * * *****************************************************************************/ permute(temp, DesInitial, 64); /***************************************************************************** * * * Split the source text into a left and right block of 32 bits. * * * *****************************************************************************/ memcpy(lblk, &temp[0], 4); memcpy(rblk, &temp[4], 4); /***************************************************************************** * * * Encipher or decipher the source text. * * * *****************************************************************************/ for (i = 0; i < 16; i++) { /************************************************************************** * * * Begin the computation of f. * * * **************************************************************************/ memcpy(fblk, rblk, 4); /************************************************************************** * * * Permute and expand the copy of the right block into 48 bits. * * * **************************************************************************/ permute(fblk, DesExpansion, 48); /************************************************************************** * * * Apply the appropriate subkey for the round. * * * **************************************************************************/ if (direction == encipher) { /*********************************************************************** * * * For enciphering, subkeys are applied in increasing order. * * * ***********************************************************************/ bit_xor(fblk, subkeys[i], xblk, 48); memcpy(fblk, xblk, 6); } else { /*********************************************************************** * * * For deciphering, subkeys are applied in decreasing order. * * * ***********************************************************************/ bit_xor(fblk, subkeys[15 - i], xblk, 48); memcpy(fblk, xblk, 6); } /************************************************************************** * * * Do the S-box substitutions. * * * **************************************************************************/ p = 0; for (j = 0; j < 8; j++) { /*********************************************************************** * * * Compute a row and column into the S-box tables. * * * ***********************************************************************/ row = (bit_get(fblk, (j * 6)+0) * 2) + (bit_get(fblk, (j * 6)+5) * 1); col = (bit_get(fblk, (j * 6)+1) * 8) + (bit_get(fblk, (j * 6)+2) * 4) + (bit_get(fblk, (j * 6)+3) * 2) + (bit_get(fblk, (j * 6)+4) * 1); /*********************************************************************** * * * Do the S-box substitution for the current six-bit block. * * * ***********************************************************************/ sblk = (unsigned char)DesSbox[j][row][col]; for (k = 4; k < 8; k++) { bit_set(fblk, p, bit_get(&sblk, k)); p++; } } /************************************************************************** * * * Do the P-box permutation to complete f. * * * **************************************************************************/ permute(fblk, DesPbox, 32); /************************************************************************** * * * Compute the XOR of the left block and f. * * * **************************************************************************/ bit_xor(lblk, fblk, xblk, 32); /************************************************************************** * * * Set the left block for the round. * * * **************************************************************************/ memcpy(lblk, rblk, 4); /************************************************************************** * * * Set the right block for the round. * * * **************************************************************************/ memcpy(rblk, xblk, 4); } /***************************************************************************** * * * Set the target text to the rejoined final right and left blocks. * * * *****************************************************************************/ memcpy(&target[0], rblk, 4); memcpy(&target[4], lblk, 4); /***************************************************************************** * * * Do the final permutation. * * * *****************************************************************************/ permute(target, DesFinal, 64); return 0; }
BitMap& BitMap::operator ^=(const BitMap& b){ return bit_xor(b); }
/** * 应用DES加密解密的主要方法 * @param source : * @param target : * @param key : * @param derection : 表示是加密还是解密 * */ static int des_main(const unsigned char *source, unsigned char *target, const unsigned char *key, DesEorD direction){ static unsigned char subkeys[16][17]; unsigned char temp[8], lkey[4], rkey[4], lblk[6], rblk[6], fblk[6], xblk[6], sblk; int row, col, i, j, k, p; /** * if key is NULL, use the subkeys as computed in a previous call. */ if (key != NULL) { //对密钥做一下备份,在密钥的备份上做操作 memcpy(temp, key, 8); //将密钥初始转换,得到一组56位的密钥 permute(temp, DesTransform, 56); //将密钥分成两组28位的数据, //先清零两组密钥 memset(lkey, 0, 4); memset(rkey, 0, 4); //0~27位放入到lkey中, 28~57位放入到rkey中 for (j = 0; j < 28; ++j) { bit_set(lkey, j, bit_get(temp, j)); bit_set(rkey, j, bit_get(temp, j + 28)); } //compute the subkeys for each round for (i = 0; i < 16; ++i) { //根据DesRotations数组中的值分别对lkey和rkey进行翻转操作 bit_rot_left(lkey, 28, DesRotations[i]); bit_rot_left(rkey, 28, DesRotations[i]); //对lkey 和rkey分别进行遍历 //取出其每一位的状态值, //放入到subkeys[i]中,lkey的位的值放入到前28位,rkey的位的值放入到后28位 for (j = 0; j < 28; ++j) { int status_lkey = bit_get(lkey, j); int status_rkey = bit_get(rkey, j); bit_set(subkeys[i], j, status_lkey); bit_set(subkeys[i], j + 28, status_rkey); } //对subkeys[i]进行转换,由56位转成48位,转换表由数组DesPermuted指定 permute(subkeys[i], DesPermuted, 48); } }//对key的预处理操作完成 //备份source到temp中,然后对temp进行操作,只备份8个字节的数据,也就是只处理64位数据 memcpy(temp, source, 8); //对源进行初始化转换,转换表由DesInitial数组指定,位数不变,依然是64位 permute(temp, DesInitial, 64); //将转换之后的源,分成两组, 每组32位,lblk前32位, rblk后32位 memcpy(lblk, &temp[0], 4); memcpy(rblk, &temp[4], 4); for (i = 0; i < 16; ++i) { //将rblk的32位复制到fblk中 memcpy(fblk, rblk, 4); //将fblk中的32位转换并扩展到48位 permute(fblk, DesExpansion, 48); //如果是加密 if (direction == encipher) { //将fblk与subkeys[i]进行异或处理,结果放置在xblk中 bit_xor(fblk, subkeys[i], xblk, 48); } else/*如果是解密*/ { //将fblk与subkeys[15 - i]进行异或处理,结果放置在xblk中 bit_xor(fblk, subkeys[15 - i], xblk, 48); } //将异或之后的结果复制到fblk中 memcpy(fblk, xblk, 6); //开始S盒转换, 将每6位转换成4位,这样48位就又转成成32位 p = 0; for (j = 0; j < 8; ++j) { //分割成6位6位的去取,转换成S盒中对应的行数列数,找到对应的S盒中的一个4位的值 int r0 = bit_get(fblk, (j * 6) + 0); int r5 = bit_get(fblk, (j * 6) + 5); row = 2 * r0 + 1 * r5; int r1 = bit_get(fblk, (j * 6) + 1); int r2 = bit_get(fblk, (j * 6) + 2); int r3 = bit_get(fblk, (j * 6) + 3); int r4 = bit_get(fblk, (j * 6) + 4); col = 8 * r1 + 4 * r2 + 2 * r3 + 1 * r4; //根据获取的行数列数,从DesSbox的第j个盒子中取出一个4位的值, sblk = (unsigned char)DesSbox[j][row][col]; for (k = 4; k < 8; ++k) { //这个值在低4位,所以遍历低4位,从左往右数,右边是低位,左边是高位 int status = bit_get(&sblk, k); //将状态值复制到fblk中的第p位,循环完成之后,fblk就是总共32位的值 bit_set(fblk, p, status); p++; } } //进行p盒转换,位数不变 permute(fblk, DesPbox, 32); //上面对fblk的操作都是对rblk的一系列的操作, //这里,将rblk与lblk进行异或操作,结果放置在xblk中, bit_xor(lblk, fblk, xblk, 32); //将异或之后的结果放入到rblk中,上一步的rblk的值放入到lblk中 memcpy(lblk, rblk, 4); memcpy(rblk, xblk, 4); //进入下一轮的循环,如此操作16次 } //将如上进过16次处理的rblk和lblk的值放入到target的前4字节和后4字节中 memcpy(&target[0], rblk, 4); memcpy(&target[4], lblk, 4); //最终转换 permute(target, DesFinal, 64); return 0; }
static int _des(const unsigned char *source, unsigned char *target, int type) { unsigned char dupbuf[8]; unsigned char lblk[6], rblk[6]; unsigned char fblk[6], xblk[6]; unsigned char sblk; int index, j, row, col; int count, k; if(source == NULL || target == NULL) return QLIB_ERR_INVAL; //Shoud use QDes_keygen() generate subkey before memcpy(dupbuf, source, 8); permute(dupbuf, dataPermuteTable, 64); memcpy(lblk, &dupbuf[0], 4); memcpy(rblk, &dupbuf[4], 4); memset(xblk, 0, 6); for(index = 0; index < 16; index++) { memcpy(fblk, rblk, 4); permute(fblk, dataExpandTable, 48);//expand from 32bits to 48bits if(type == DES_ENCRYPT) { bit_xor(fblk, subkeys[index], xblk, 48); memcpy(fblk, xblk, 6); } else { bit_xor(fblk, subkeys[15-index], xblk, 48); memcpy(fblk, xblk, 6); } count = 0; for(j = 0; j < 8; j++) { row = bit_get(fblk, (j*6)+0)*2 + bit_get(fblk, (j*6)+5)*1; col = bit_get(fblk, (j*6)+1)*8 + bit_get(fblk, (j*6)+2)*4 + bit_get(fblk, (j*6)+3)*2 + bit_get(fblk, (j*6)+4)*1; sblk = (unsigned char)dataSubTable[j][row][col]; for(k = 4; k < 8; k++) { bit_set(fblk, count, bit_get(&sblk, k)); count++; } } permute(fblk, dataScatterTable, 32); bit_xor(lblk, fblk, xblk, 32); memcpy(lblk, rblk, 4); memcpy(rblk, xblk, 4); } memcpy(&target[0], rblk, 4); memcpy(&target[4], lblk, 4); permute(target, dataFinalTable, 64); }
void CPU::exec32(const Instruction32 &insn) { switch(insn.OP) { case 0x00: { uint32_t &rD = r[insn.spform.rD]; uint32_t &rA = r[insn.spform.rA]; uint32_t &rB = r[insn.spform.rB]; switch(insn.spform.func6) { // nop case 0x00: /* nothing */ break; // br{cond}[l] rA case 0x04: if(conditional(insn.spform.rB)) branch(rA - 4, insn.spform.CU); break; // add[.c] rD, rA, rB case 0x08: rD = add(rA, rB, insn.spform.CU); break; // addc[.c] rD, rA, rB case 0x09: rD = addc(rA, rB, insn.spform.CU); break; // sub[.c] rD, rA, rB case 0x0A: rD = sub(rA, rB, insn.spform.CU); break; // subc[.c] rD, rA, rB case 0x0B: rD = subc(rA, rB, insn.spform.CU); break; // cmp{tcs}.c rA, rB case 0x0C: cmp(rA, rB, insn.spform.rD & 0x03, insn.spform.CU); break; // cmpz{tcs}.c rA, rB case 0x0D: cmp(rA, 0, insn.spform.rD & 0x03, insn.spform.CU); break; // neg[.c] rD, rA case 0x0F: rD = sub(0, rA, insn.spform.CU); break; // and[.c] rD, rA, rB case 0x10: rD = bit_and(rA, rB, insn.spform.CU); break; // or[.c] rD, rA, rB case 0x11: rD = bit_or(rA, rB, insn.spform.CU); break; // not[.c] rD, rA, rB case 0x12: rD = bit_xor(rA, ~0, insn.spform.CU); break; // xor[.c] rD, rA, rB case 0x13: rD = bit_or(rA, rB, insn.spform.CU); break; // bitclr[.c] rD, rA, imm5 case 0x14: rD = bit_and(rA, ~(1 << insn.spform.rB), insn.spform.CU); break; // bitset[.c] rD, rA, imm5 case 0x15: rD = bit_or(rA, 1 << insn.spform.rB, insn.spform.CU); break; // bittst.c rA, imm5 case 0x16: bit_and(rA, 1 << insn.spform.rB, insn.spform.CU); break; // bittgl[.c] rA, imm5 case 0x17: rD = bit_xor(rA, 1 << insn.spform.rB, insn.spform.CU); break; // sll[.c] rA, imm5 case 0x18: rD = sll(rA, insn.spform.rB, insn.spform.CU); break; // srl[.c] rA, imm5 case 0x1A: rD = srl(rA, insn.spform.rB, insn.spform.CU); break; // sra[.c] rA, imm5 case 0x1B: rD = sra(rA, insn.spform.rB, insn.spform.CU); break; // mul rA, rD case 0x20: ce_op(rA, rD, std::multiplies<int64_t>()); break; // mulu rA, rD case 0x21: ce_op(rA, rD, std::multiplies<uint64_t>()); break; // div rA, rD case 0x22: ce_op(rA, rD, std::divides<int64_t>()); break; // divu rA, rD case 0x23: ce_op(rA, rD, std::divides<uint64_t>()); break; // mfce{hl} rD[, rA] case 0x24: switch(insn.spform.rB) { case 0x01: rD = CEL; break; case 0x02: rD = CEH; break; case 0x03: rD = CEH; rA = CEL; break; } break; // mtce{hl} rD[, rA] case 0x25: switch(insn.spform.rB) { case 0x01: CEL = rD; break; case 0x02: CEH = rD; break; case 0x03: CEH = rD; CEL = rA; break; } break; // mfsr rA, Srn case 0x28: rA = sr[insn.spform.rB]; // mtsr rA, Srn case 0x29: sr[insn.spform.rB] = rA; // t{cond} case 0x2A: T = conditional(insn.spform.rB); break; // mv{cond} rD, rA case 0x2B: if(conditional(insn.spform.rB)) rD = rA; break; // extsb[.c] rD, rA case 0x2C: rD = sign_extend(rA, 8); if(insn.spform.CU) basic_flags(rD); break; // extsh[.c] rD, rA case 0x2D: rD = sign_extend(rA, 16); if(insn.spform.CU) basic_flags(rD); break; // extzb[.c] rD, rA case 0x2E: rD = bit_and(rA, 0x000000FF, insn.spform.CU); break; // extzh[.c] rD, rA case 0x2F: rD = bit_and(rA, 0x0000FFFF, insn.spform.CU); break; // slli[.c] rD, rA, imm5 case 0x38: rD = sll(rA, insn.spform.rB, insn.spform.CU); break; // srli[.c] rD, rA, imm5 case 0x3A: rD = srl(rA, insn.spform.rB, insn.spform.CU); break; // srai[.c] rD, rA, imm5 case 0x3B: rD = sra(rA, insn.spform.rB, insn.spform.CU); break; default: debugDump(); } } break; case 0x01: { uint32_t &rD = r[insn.iform.rD]; switch(insn.iform.func3) { // addi[.c] rD, imm16 case 0x00: rD = add(rD, sign_extend(insn.iform.Imm16, 16), insn.iform.CU); break; // cmpi.c rD, imm16 case 0x02: cmp(rD, sign_extend(insn.iform.Imm16, 16), 3, insn.iform.CU); break; // andi.c rD, imm16 case 0x04: rD = bit_and(rD, insn.iform.Imm16, insn.iform.CU); break; // ori.c rD, imm16 case 0x05: rD = bit_or(rD, insn.iform.Imm16, insn.iform.CU); break; // ldi rD, imm16 case 0x06: rD = sign_extend(insn.iform.Imm16, 16); break; default: debugDump(); } } break; case 0x02: { // j[l] imm24 if(insn.jform.LK) link(); // Update PC pc &= 0xFC000000; pc |= (insn.jform.Disp24 << 1) - 4; } break; case 0x03: { uint32_t &rD = r[insn.rixform.rD]; uint32_t &rA = r[insn.rixform.rA]; // Pre-increment rA += sign_extend(insn.rixform.Imm12, 12); switch(insn.rixform.func3) { // lw rD, [rA, imm12]+ case 0x00: rD = miu.readU32(rA); break; // lh rD, [rA, imm12]+ case 0x01: rD = sign_extend(miu.readU16(rA), 16); break; // lhu rD, [rA, imm12]+ case 0x02: rD = miu.readU16(rA); break; // lb rD, [rA, imm12]+ case 0x03: rD = sign_extend(miu.readU8(rA), 8); break; // sw rD, [rA, imm12]+ case 0x04: miu.writeU32(rA, rD); break; // sh rD, [rA, imm12]+ case 0x05: miu.writeU16(rA, rD); break; // lbu rD, [rA, imm12]+ case 0x06: rD = miu.readU8(rA); break; // sb rD, [rA, imm12]+ case 0x07: miu.writeU8(rA, rD); break; default: debugDump(); } } break; case 0x04: { // b{cond}[l] if(conditional(insn.bcform.BC)) { if(insn.bcform.LK) link(); pc += sign_extend(((insn.bcform.Disp18_9 << 9) | insn.bcform.Disp8_0) << 1, 20) - 4; } } break; case 0x05: { uint32_t &rD = r[insn.iform.rD]; uint32_t imm16 = insn.iform.Imm16 << 16; switch(insn.iform.func3) { // addis[.c] rD, imm16 case 0x00: rD = add(rD, imm16, insn.iform.CU); break; // cmpis.c rD, imm16 case 0x02: cmp(rD, imm16, 3, insn.iform.CU); break; // andis.c rD, imm16 case 0x04: rD = bit_and(rD, imm16, insn.iform.CU); break; // oris.c rD, imm16 case 0x05: rD = bit_or(rD, imm16, insn.iform.CU); break; // ldis rD, imm16 case 0x06: rD = imm16; break; default: debugDump(); } } break; case 0x06: { uint32_t &rD = r[insn.crform.rD]; uint32_t &crA = cr[insn.crform.crA]; switch(insn.crform.CR_OP) { // mtcr rD, crA case 0x00: crA = rD; break; // mfcr rD, crA case 0x01: rD = crA; break; // rte case 0x84: branch(cr5 - 4, false); /* TODO: missing PSR */ break; default: debugDump(); } } break; case 0x07: { uint32_t &rD = r[insn.rixform.rD]; uint32_t &rA = r[insn.rixform.rA]; switch(insn.rixform.func3) { // lw rD, [rA]+, imm12 case 0x00: rD = miu.readU32(rA); break; // lh rD, [rA]+, imm12 case 0x01: rD = sign_extend(miu.readU16(rA), 16); break; // lhu rD, [rA]+, imm12 case 0x02: rD = miu.readU16(rA); break; // lb rD, [rA]+, imm12 case 0x03: rD = sign_extend(miu.readU8(rA), 8); break; // sw rD, [rA]+, imm12 case 0x04: miu.writeU32(rA, rD); break; // sh rD, [rA]+, imm12 case 0x05: miu.writeU16(rA, rD); break; // lbu rD, [rA]+, imm12 case 0x06: rD = miu.readU8(rA); break; // sb rD, [rA]+, imm12 case 0x07: miu.writeU8(rA, rD); break; default: debugDump(); } // Post-increment rA += sign_extend(insn.rixform.Imm12, 12); } break; case 0x08: { // addri[.c] rD, rA, imm14 uint32_t &rD = r[insn.riform.rD]; uint32_t &rA = r[insn.riform.rA]; uint32_t imm14 = sign_extend(insn.riform.Imm14, 14); rD = add(rA, imm14, insn.riform.CU); } break; case 0x0C: { // andri[.c] rD, rA, imm14 uint32_t &rD = r[insn.riform.rD]; uint32_t &rA = r[insn.riform.rA]; uint32_t imm14 = insn.riform.Imm14; rD = bit_and(rA, imm14, insn.riform.CU); } break; case 0x0D: { // orri[.c] rD, rA, imm14 uint32_t &rD = r[insn.riform.rD]; uint32_t &rA = r[insn.riform.rA]; uint32_t imm14 = insn.riform.Imm14; rD = bit_or(rA, imm14, insn.riform.CU); } break; case 0x10: { // lw rD, [rA, imm15] uint32_t &rD = r[insn.mform.rD]; uint32_t &rA = r[insn.mform.rA]; uint32_t imm15 = sign_extend(insn.mform.Imm15, 15); rD = miu.readU32(rA + imm15); } break; case 0x11: { // lh rD, [rA, imm15] uint32_t &rD = r[insn.mform.rD]; uint32_t &rA = r[insn.mform.rA]; uint32_t imm15 = sign_extend(insn.mform.Imm15, 15); rD = sign_extend(miu.readU16(rA + imm15), 16); } break; case 0x12: { // lhu rD, [rA, imm15] uint32_t &rD = r[insn.mform.rD]; uint32_t &rA = r[insn.mform.rA]; uint32_t imm15 = sign_extend(insn.mform.Imm15, 15); rD = miu.readU16(rA + imm15); } break; case 0x13: { // lb rD, [rA, imm15] uint32_t &rD = r[insn.mform.rD]; uint32_t &rA = r[insn.mform.rA]; uint32_t imm15 = sign_extend(insn.mform.Imm15, 15); rD = sign_extend(miu.readU8(rA + imm15), 8); } break; case 0x14: { // sw rD, [rA, imm15] uint32_t &rD = r[insn.mform.rD]; uint32_t &rA = r[insn.mform.rA]; uint32_t imm15 = sign_extend(insn.mform.Imm15, 15); miu.writeU32(rA + imm15, rD); } break; case 0x15: { // sh rD, [rA, imm15] uint32_t &rD = r[insn.mform.rD]; uint32_t &rA = r[insn.mform.rA]; uint32_t imm15 = sign_extend(insn.mform.Imm15, 15); miu.writeU16(rA + imm15, rD); } break; case 0x16: { // lbu rD, [rA, imm15] uint32_t &rD = r[insn.mform.rD]; uint32_t &rA = r[insn.mform.rA]; uint32_t imm15 = sign_extend(insn.mform.Imm15, 15); rD = miu.readU8(rA + imm15); } break; case 0x17: { // sb rD, [rA, imm15] uint32_t &rD = r[insn.mform.rD]; uint32_t &rA = r[insn.mform.rA]; uint32_t imm15 = sign_extend(insn.mform.Imm15, 15); miu.writeU8(rA + imm15, rD); } break; case 0x18: // cache op, [rA, imm15] break; default: debugDump(); } }
void CPU::exec16(const Instruction16 &insn) { switch(insn.OP) { case 0x00: switch(insn.rform.func4) { // nop! case 0x00: /* noting */ break; // mlfh! rDg0, rAg1 case 0x01: g0[insn.rform.rD] = g1[insn.rform.rA]; break; // mhfl! rDg1, rAg0 case 0x02: g1[insn.rform.rD] = g0[insn.rform.rA]; break; // mv! rDg0, rAg0 case 0x03: g0[insn.rform.rD] = g0[insn.rform.rA]; break; // br{cond}! rAg0 case 0x04: if(conditional(insn.rform.rD)) branch(g0[insn.rform.rA] - 2, false); break; // t{cond}! case 0x05: T = conditional(insn.rform.rD); break; default: debugDump(); } break; case 0x01: { uint32_t &rA = g0[insn.rform.rA]; // uint32_t &rD = g0[insn.rform.rD]; switch(insn.rform.func4) { // mtce{lh}! rA case 0x00: switch(insn.rform.rD) { case 0x00: CEL = rA; break; case 0x01: CEH = rA; break; } break; // mfce{lh}! rA case 0x01: switch(insn.rform.rD) { case 0x00: rA = CEL; break; case 0x01: rA = CEH; break; } break; default: debugDump(); } } break; case 0x02: { uint32_t &rA = g0[insn.rform.rA]; uint32_t &rD = g0[insn.rform.rD]; uint32_t &rAh = g0[insn.rhform.rA]; uint32_t &rDh = g[insn.rhform.H][insn.rhform.rD]; switch(insn.rform.func4) { // add! rDg0, rAg0 case 0x00: rD = add(rD, rA, true); break; // sub! rDg0, rAg0 case 0x01: rD = sub(rD, rA, true); break; // neg! rDg0, rAg0 case 0x02: rD = sub(0, rA, true); break; // cmp! rDg0, rAg0 case 0x03: sub(rD, rA, true); break; // and! rDg0, rAg0 case 0x04: rD = bit_and(rD, rA, true); break; // or! rDg0, rAg0 case 0x05: rD = bit_or(rD, rA, true); break; // not! rDg0, rAg0 case 0x06: rD = bit_xor(rA, ~0, true); break; // xor! rDg0, rAg0 case 0x07: rD = bit_xor(rD, rA, true); break; // lw! rDg0, [rAg0] case 0x08: rD = miu.readU32(rA); break; // lh! rDg0, [rAg0] case 0x09: rD = sign_extend(miu.readU16(rA), 16); break; // pop! rDgh, [rAg0] case 0x0A: rDh = miu.readU32(rAh); rAh += 4; break; // lbu! rDg0, [rAg0] case 0x0B: rD = miu.readU8(rA); break; // sw! rDg0, [rAg0] case 0x0C: miu.writeU32(rA, rD); break; // sh! rDg0, [rAg0] case 0x0D: miu.writeU16(rA, rD); break; // push! rDgh, [rAg0] case 0x0E: miu.writeU32(rAh -= 4, rDh); break; // sb! rDg0, [rAg0] case 0x0F: miu.writeU8(rA, rD); break; } } break; case 0x03: { // j[l]! imm11 if(insn.jform.LK) link(); pc &= 0xFFFFF000; pc |= (insn.jform.Disp11 << 1) - 2; } break; case 0x04: { // b{cond}! imm8 if(conditional(insn.bxform.EC)) pc += (sign_extend(insn.bxform.Imm8, 8) << 1) - 2; } break; case 0x05: // ldiu! imm8 g0[insn.iform2.rD] = insn.iform2.Imm8; break; case 0x06: { uint32_t &rD = g0[insn.iform1.rD]; uint32_t imm = 1 << insn.iform1.Imm5; switch(insn.iform1.func3) { // srli! rD, imm5 case 0x03: rD = srl(rD, insn.iform1.Imm5, true); break; // bitclr! rD, imm5 case 0x04: rD = bit_and(rD, ~imm, true); break; // bitset! rD, imm5 case 0x05: rD = bit_or(rD, imm, true); break; // bittst! rD, imm5 case 0x06: bit_and(rD, imm, true); break; default: debugDump(); } } break; case 0x07: { uint32_t &rD = g0[insn.iform1.rD]; uint32_t imm = insn.iform1.Imm5 << 2; switch(insn.iform1.func3) { // lwp! rDg0, imm case 0x00: rD = miu.readU32(r2 + imm); break; // lbup! rDg0, imm case 0x01: rD = miu.readU8(r2 + imm); break; // lhp! rDg0, imm case 0x03: rD = sign_extend(miu.readU8(r2 + imm), 16); break; // swp! rDg0, imm case 0x04: miu.writeU32(r2 + imm, rD); break; // shp! rDg0, imm case 0x05: miu.writeU16(r2 + imm, rD); break; // sbp! rDg0, imm case 0x07: miu.writeU32(r2 + imm, rD); break; default: debugDump(); } } break; default: debugDump(); } }
int main(int argc, char **argv) { unsigned char bits1[8], bits2[8], bits3[8]; int i; /***************************************************************************** * Perform some bit operations using 64-bit buffers. * *****************************************************************************/ for (i = 0; i < 8; i++) { bits1[i] = 0x00; bits2[i] = 0x00; bits3[i] = 0x00; } fprintf(stdout, "Initially\n"); fprintf(stdout, "bits1: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits1[0], bits1[1], bits1[2], bits1[3], bits1[4], bits1[5], bits1[6], bits1[7]); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); bit_set(bits1, 15, 1); bit_set(bits1, 16, 1); bit_set(bits1, 32, 1); bit_set(bits1, 63, 1); bit_set(bits2, 0, 1); bit_set(bits2, 15, 1); fprintf(stdout, "After setting bits 15, 16, 32, 63 of bits1 and bits 00, 15 " "of bits2\n"); fprintf(stdout, "bits1: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits1[0], bits1[1], bits1[2], bits1[3], bits1[4], bits1[5], bits1[6], bits1[7]); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); fprintf(stdout, "Bit 63 of bits1 is %d\n", bit_get(bits1, 63)); fprintf(stdout, "Bit 62 of bits1 is %d\n", bit_get(bits1, 62)); fprintf(stdout, "Bit 00 of bits2 is %d\n", bit_get(bits2, 0)); fprintf(stdout, "Bit 01 of bits2 is %d\n", bit_get(bits2, 1)); bit_xor(bits1, bits2, bits3, 32); fprintf(stdout, "bits3 is bits1 XOR bits2 (32 bits)\n"); fprintf(stdout, "bits3: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits3[0], bits3[1], bits3[2], bits3[3], bits3[4], bits3[5], bits3[6], bits3[7]); bit_xor(bits1, bits2, bits3, 64); fprintf(stdout, "bits3 is bits1 XOR bits2 (64 bits)\n"); fprintf(stdout, "bits3: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits3[0], bits3[1], bits3[2], bits3[3], bits3[4], bits3[5], bits3[6], bits3[7]); bit_rot_left(bits1, 64, 1); fprintf(stdout, "After rotating bits1 left x 1 (64 bits)\n"); fprintf(stdout, "bits1: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits1[0], bits1[1], bits1[2], bits1[3], bits1[4], bits1[5], bits1[6], bits1[7]); bit_rot_left(bits2, 64, 1); fprintf(stdout, "After rotating bits2 left x 1 (64 bits)\n"); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); bit_rot_left(bits2, 16, 7); fprintf(stdout, "After rotating bits2 left x 7 (16 bits)\n"); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); bit_rot_left(bits2, 8, 2); fprintf(stdout, "After rotating bits2 left x 2 (8 bits)\n"); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); for (i = 0; i < 8; i++) { bits2[i] = 0x00; } bit_set(bits2, 0, 1); bit_set(bits2, 3, 1); bit_set(bits2, 8, 1); bit_set(bits2, 27, 1); fprintf(stdout, "After clearing and setting bits 0, 3, 8, 27 of bits2\n"); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); bit_rot_left(bits2, 11, 6); fprintf(stdout, "After rotating bits2 left x 6 (11 bits)\n"); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); for (i = 0; i < 8; i++) { bits2[i] = 0x00; } bit_set(bits2, 0, 1); bit_set(bits2, 3, 1); bit_set(bits2, 8, 1); bit_set(bits2, 27, 1); fprintf(stdout, "After clearing and setting bits 0, 3, 8, 27 of bits2\n"); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); bit_rot_left(bits2, 28, 4); fprintf(stdout, "After rotating bits2 left x 4 (28 bits)\n"); fprintf(stdout, "bits2: %02x %02x %02x %02x %02x %02x %02x %02x\n", bits2[0], bits2[1], bits2[2], bits2[3], bits2[4], bits2[5], bits2[6], bits2[7]); return 0; }