Beispiel #1
0
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;

}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}
Beispiel #4
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];
}
Beispiel #5
0
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;

}
Beispiel #6
0
BitMap& BitMap::operator ^=(const BitMap& b){
    return bit_xor(b);
}
Beispiel #7
0
/**
 * 应用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;
}
Beispiel #8
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);
}
Beispiel #9
0
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();
	}
}
Beispiel #10
0
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;

}