вопрос в реализации функции в симуляторе руки для формата 4 - PullRequest
0 голосов
/ 10 июля 2020

Мой вопрос касается представления бит переноса и арифметического c сдвига вправо в моей функции имитации большого пальца руки. мне нужно создать логическую переменную, если операционный код является двоичным битовым значением AD C, тогда я добавляю логическую переменную как 1, а если нет, то это SB C? также, как представить logi c ASR в моем коде?

формат 4

инструкции формата 4 с помощью кода операции

case 2:           // format 4
    op = (instr >> 6) & 0xF;
    rd = instr & 7;
    rs = (instr >> 3) & 7;
    if (op == 0)
    {
        cout << " AND " << rd << "," << rs << endl;
        Regs[rd] = Regs[rd] & Regs[rs];
    }
    else if (op == 1)
    {
        cout << " EOR " << rd << "," << rs << endl;
        Regs[rd] = Regs[rd] ^ Regs[rs];
    }
    else if (op == 2)
    {
        cout << " LSL " << rd << "," << rs << endl;
        Regs[rd] = Regs[rd] << Regs[rs];
    }
    else if (op == 3)
    {
        cout << " LSR " << rd << "," << rs << endl;
        Regs[rd] = Regs[rd] >> Regs[rs];
    }
    **else if (op == 4)
    {
        cout << " ASR  " << rd << "," << rs << endl;
        Regs[rd] = Regs[rd] >> Regs[rs];
    }**
    **else if (op == 5)
    {
        cout << " ADC " << rd << "," << rs << endl;
        Regs[rd] = Regs[rd] & Regs[rs];
    }
    else if (op == 6)
    {
        cout << " SBC " << rd << "," << rs << endl;
        Regs[rd] = Regs[rd] - Regs[rs];
    }**
    break;

1 Ответ

0 голосов
/ 12 июля 2020

Я просто дам вам для размышления рабочий код.

void do_cflag ( unsigned int a, unsigned int b, unsigned int c )
{
    unsigned int rc;

    cpsr&=~CPSR_C;
    rc=(a&0x7FFFFFFF)+(b&0x7FFFFFFF)+c; //carry in
    rc = (rc>>31)+(a>>31)+(b>>31);  //carry out
    if(rc&2) cpsr|=CPSR_C;
}    
void do_cflag_bit ( unsigned int x )
{
   if(x) cpsr|=CPSR_C; else cpsr&=~CPSR_C;
}

...

    //SUB(1)
    if((inst&0xFE00)==0x1E00)
    {
        rd=(inst>>0)&7;
        rn=(inst>>3)&7;
        rb=(inst>>6)&7;
if(DISS) fprintf(stderr,"subs r%u,r%u,#0x%X\n",rd,rn,rb);
        ra=read_register(rn);
        rc=ra-rb;
        write_register(rd,rc);
        do_nflag(rc);
        do_zflag(rc);
        do_cflag(ra,~rb,1);
        do_vflag(ra,~rb,1);
        return(0);
    }
    //SBC
    if((inst&0xFFC0)==0x4180)
    {
        rd=(inst>>0)&0x7;
        rm=(inst>>3)&0x7;
if(DISS) fprintf(stderr,"sbc r%u,r%u\n",rd,rm);
        ra=read_register(rd);
        rb=read_register(rm);
        rc=ra-rb;
        if(!(cpsr&CPSR_C)) rc--;
        write_register(rd,rc);
        do_nflag(rc);
        do_zflag(rc);
        if(cpsr&CPSR_C)
        {
            do_cflag(ra,~rb,1);
            do_vflag(ra,~rb,1);
        }
        else
        {
            do_cflag(ra,~rb,0);
            do_vflag(ra,~rb,0);
        }
        return(0);
    }
    //ADC
    if((inst&0xFFC0)==0x4140)
    {
        rd=(inst>>0)&0x07;
        rm=(inst>>3)&0x07;
if(DISS) fprintf(stderr,"adc r%u,r%u\n",rd,rm);
        ra=read_register(rd);
        rb=read_register(rm);
        rc=ra+rb;
        if(cpsr&CPSR_C) rc++;
        write_register(rd,rc);
        do_nflag(rc);
        do_zflag(rc);
        if(cpsr&CPSR_C) { do_cflag(ra,rb,1); do_vflag(ra,rb,1); }
        else            { do_cflag(ra,rb,0); do_vflag(ra,rb,0); }
        return(0);
    }
    //ADD(3) three registers
    if((inst&0xFE00)==0x1800)
    {
        rd=(inst>>0)&0x7;
        rn=(inst>>3)&0x7;
        rm=(inst>>6)&0x7;
if(DISS) fprintf(stderr,"adds r%u,r%u,r%u\n",rd,rn,rm);
        ra=read_register(rn);
        rb=read_register(rm);
        rc=ra+rb;
        write_register(rd,rc);
        do_nflag(rc);
        do_zflag(rc);
        do_cflag(ra,rb,0);
        do_vflag(ra,rb,0);
        return(0);
    }

    //ASR(2) two register
    if((inst&0xFFC0)==0x4100)
    {
        rd=(inst>>0)&0x07;
        rs=(inst>>3)&0x07;
if(DISS) fprintf(stderr,"asrs r%u,r%u\n",rd,rs);
        rc=read_register(rd);
        rb=read_register(rs);
        rb&=0xFF;
        if(rb==0)
        {
        }
        else if(rb<32)
        {
            do_cflag_bit(rc&(1<<(rb-1)));
            ra=rc&0x80000000;
            rc>>=rb;
            if(ra) //asr, sign is shifted in
            {
                rc|=(~0)<<(32-rb);
            }
        }
        else
        {
            if(rc&0x80000000)
            {
                do_cflag_bit(1);
                rc=(~0);
            }
            else
            {
                do_cflag_bit(0);
                rc=0;
            }
        }
        write_register(rd,rc);
        do_nflag(rc);
        do_zflag(rc);
        return(0);
    }
...