#ifdef INARMC
unsigned long thumbbranch;

void TPop(unsigned long opcode)
{
        int c;
        addr=armregs[13];
        for (c=0;c<8;c++)
        {
                if (opcode&(1<<c))
                {
                        armregs[c]=readmeml(addr);
                        cycles--;
                        if (output && !c) rpclog("POP R0 = %08X from %08X\n",armregs[c],addr);
                        addr+=4;
                }
        }
        if (opcode&0x100)
        {
                armregs[15]=readmeml(addr);
                cycles--;
                addr+=4;
                armregs[15]&=~1;
                armregs[15]+=2;
                refillpipeline();
//                printf("POP PC %08X\n",armregs[15]);
        }
        armregs[13]=addr;
}
void TPush(unsigned long opcode)
{
        int c;
//        if (output) rpclog("PUSH %04X\n",opcode);
        addr=armregs[13]-countbits(opcode&0x1FF);
        armregs[13]=addr;
        for (c=0;c<8;c++)
        {
                if (opcode&(1<<c))
                {
                        writememl(addr,armregs[c]);
                        cycles--;
                        addr+=4;
                }
        }
        if (opcode&0x100)
        {
                if (output) rpclog("Writing LR (%08X) to %08X\n",armregs[14],addr);
                writememl(addr,armregs[14]);
                cycles--;
        }
}

void TMov(unsigned long opcode)
{
        armregs[TRD2]=opcode&0xFF;
        setzn(armregs[TRD2]);
}
void TMovHigh(unsigned long opcode)
{
        templ=(opcode>>3)&15;
        templ2=TRD;
        if (opcode&0x80) templ2|=8;
//        printf("R%i=R%i\n",templ2,templ);
        armregs[templ2]=armregs[templ];
        if (templ==15) armregs[templ2]&=~1;
        if (templ2==15)
        {
                armregs[15]+=2;
                refillpipeline();
        }
}

void TLsl(unsigned long opcode)
{
        armregs[16]&=~CFLAG;
        templ=(opcode>>6)&31;
        if ((armregs[TRM]<<(templ-1))>>31) armregs[16]|=CFLAG;
        armregs[TRD]=armregs[TRM]<<templ;
        setzn(armregs[TRD]);
}
void TLsr(unsigned long opcode)
{
        armregs[16]&=~CFLAG;
        templ=(opcode>>6)&31;
        if ((armregs[TRM]>>(templ-1))&1) armregs[16]|=CFLAG;
        armregs[TRD]=armregs[TRM]>>templ;
        setzn(armregs[TRD]);
}
void TAsr(unsigned long opcode)
{
        armregs[16]&=~CFLAG;
        templ=(opcode>>6)&31;
        if ((armregs[TRM]>>(templ-1))&1) armregs[16]|=CFLAG;
        armregs[TRD]=(int)armregs[TRM]>>templ;
        setzn(armregs[TRD]);
}

void TLdrHImm(unsigned long opcode)
{
        addr=armregs[TRN]+(((opcode>>6)&31)<<1);
        armregs[TRD]=readmemw(addr);
        cycles--;
}
void TLdrImm(unsigned long opcode)
{
        addr=armregs[TRN]+(((opcode>>6)&31)<<2);
        armregs[TRD]=readmeml(addr);
        if (addr&3) armregs[TRD]=ldrresult(armregs[TRD],addr);
        cycles--;
}
void TLdrReg(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        armregs[TRD]=readmeml(addr);
        if (addr&3) armregs[TRD]=ldrresult(armregs[TRD],addr);
        cycles--;
}
void TLdrPC(unsigned long opcode)
{
        addr=(armregs[15]&~3)+((opcode&0xFF)<<2);
        armregs[TRD2]=readmeml(addr);
        if (addr&3) armregs[TRD2]=ldrresult(armregs[TRD2],addr);
        cycles--;
}
void TLdrSP(unsigned long opcode)
{
        addr=armregs[13]+((opcode&0xFF)<<2);
        armregs[TRD2]=readmeml(addr);
        if (addr&3) armregs[TRD2]=ldrresult(armregs[TRD2],addr);
        cycles--;
}
void TLdrbImm(unsigned long opcode)
{
        addr=armregs[TRN]+((opcode>>6)&31);
        armregs[TRD]=readmemb(addr);
        cycles--;
}
void TLdrSH(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        armregs[TRD]=readmemw(addr);
        if (armregs[TRD]&0x8000) armregs[TRD]|=0xFFFF0000;
        cycles--;
}
void TLdrH(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        armregs[TRD]=readmemw(addr);
        cycles--;
}
void TLdrB(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        armregs[TRD]=readmemb(addr);
        cycles--;
}

void TLdrSB(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        armregs[TRD]=readmemb(addr);
        if (armregs[TRD]&0x80) armregs[TRD]|=0xFFFFFF00;
        cycles--;
}
/*void TLdrSH(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        armregs[TRD]=readmemw(addr);
        if (armregs[TRD]&0x8000) armregs[TRD]|=0xFFFF0000;
}*/

void TStrImm(unsigned long opcode)
{
        addr=armregs[TRN]+(((opcode>>6)&31)<<2);
        writememl(addr,armregs[TRD]);
        cycles--;
}
void TStrHImm(unsigned long opcode)
{
        addr=armregs[TRN]+(((opcode>>6)&31)<<1);
        writememw(addr,armregs[TRD]);
        cycles--;
}
void TStrReg(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        writememl(addr,armregs[TRD]);
        cycles--;
}
void TStrH(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        writememw(addr,armregs[TRD]);
        cycles--;
}
void TStrB(unsigned long opcode)
{
        addr=armregs[TRN]+armregs[TRM2];
        writememb(addr,armregs[TRD]);
        cycles--;
}
void TStrbImm(unsigned long opcode)
{
        addr=armregs[TRN]+((opcode>>6)&31);
        writememb(addr,armregs[TRD]);
        cycles--;
}
void TStrSP(unsigned long opcode)
{
        addr=armregs[13]+((opcode&0xFF)<<2);
        writememl(addr,armregs[TRD2]);
        cycles--;
}

void TB(unsigned long opcode)
{
        addr=opcode&0x7FF;
        if (opcode&0x400) addr|=0xFFFFFC00;
        armregs[15]+=(addr<<1)+2;
        //rpclog("TB %i ",cycles);
        refillpipeline();
        //rpclog("%i\n",cycles);
}

void TBcond(unsigned long opcode)
{
//        rpclog("Bcond %X %X %i\n",(opcode>>8)&0xF,(*pcpsr)>>28,flaglookup[(opcode>>8)&0xF][(*pcpsr)>>28]);
        if (flaglookup[(opcode>>8)&0xF][(*pcpsr)>>28])
        {
                addr=opcode&0xFF;
                if (opcode&0x80) addr|=0xFFFFFF00;
//                rpclog("Bcond %08X\n",addr);
                armregs[15]+=(addr<<1)+2;
                refillpipeline();
        }
        blockend=1;
}
void TBL1(unsigned long opcode)
{
        dontint=1;
        thumbbranch=opcode&0x7FF;
}
void TBL2(unsigned long opcode)
{
        dontint=0;
        addr=thumbbranch<<12;
        if (addr&0x400000) addr|=0xFF800000;
        addr+=armregs[15];
        addr+=((opcode&0x7FF)<<1);
//        printf("Jump to %08X\n",addr);
        armregs[14]=(armregs[15]-2)|1;
        armregs[15]=addr;
        refillpipeline();

}
void TBXReg(unsigned long opcode)
{
        if (opcode&0x80)
        {
                printf("BX with 80 set!\n");
                dumpregs();
                exit(-1);
        }
        armregs[15]=armregs[(opcode>>3)&15];
        if (armregs[15]&1)
        {
                armregs[15]&=~1;
                armregs[15]+=2;
        }
        else
        {
                armregs[15]&=~3;
                armregs[16]&=~0x20;
                r15mask=0xFFFFFFFC;
                r15off=8;
                blockend=1;
        }
        refillpipeline();
}

void TSWI(unsigned long opcode)
{
        lastbiosop=bios[0x190>>2];
/*        printf("SWI %04X %08X %08X %08X  %08X %i %04X  %04X %04X %04X %04X\n",opcode,armregs[0],armregs[1],armregs[2],PC,romins,lcd.ctrl,lcd.bgctrl[0],lcd.bgctrl[1],lcd.bgctrl[2],lcd.bgctrl[3]);
        if (opcode==0xDF0B && (armregs[0]>>28))
        {
                fflush(stdout);
                dumpregs();
                exit(-1);
        }*/
//        if (opcode==0xDF11 && !armregs[0]) return;
/*        if (armregs[0]>>28)
        {
                dumpregs();
                exit(-1);
        }*/
/*        if (output)
        {
                dumpregs();
                exit(-1);
        }*/
//        if (opcode==0xDF0C && armregs[0]==0x3007F38 && armregs[1]==0x3000604 && armregs[2]==0x10000B0 && lcd.bgctrl[0]==0x7E01) output=1;
//        if (opcode==0xDF12 && armregs[0]==0x8E9C798) output=1;
//        if (opcode==0xDF06 && armregs[0]==0x7D0 && armregs[1]==0xA && PC==0x80B6618) output=1;
//        output=1;
//        rpclog("CPSR %08X R13 %08X\n",armregs[16],armregs[13]);
        templ=armregs[15]-2;
        spsr[SUPERVISOR]=armregs[16];
        updatemode(SUPERVISOR|16);
        armregs[14]=templ&~1;
        armregs[16]&=~0x3F;
        armregs[16]|=0x93;
        armregs[15]=0x000000008;
        refillpipeline();
                r15mask=0xFFFFFFFC;
                r15off=8;
                blockend=1;
//        rpclog("CPSR NOW %08X\n",armregs[16]);
}

void TAddImm(unsigned long opcode)
{
        templ=(opcode>>6)&7;
        setadd(armregs[TRN],templ,armregs[TRN]+templ);
        armregs[TRD]=armregs[TRN]+templ;
}
void TAddImm8(unsigned long opcode)
{
        setadd(armregs[TRD2],opcode&0xFF,armregs[TRD2]+(opcode&0xFF));
        armregs[TRD2]+=(opcode&0xFF);
}
void TAddReg(unsigned long opcode)
{
        setadd(armregs[TRN],armregs[TRM2],armregs[TRN]+armregs[TRM2]);
        armregs[TRD]=armregs[TRN]+armregs[TRM2];
}
void TAddPC(unsigned long opcode)
{
//        setadd((armregs[15]&~3),(opcode&0xFF)<<2,((armregs[15]&~3))+((opcode&0xFF)<<2));
        armregs[TRD2]=((opcode&0xFF)<<2)+((armregs[15]&~3));
}
void TAddSP(unsigned long opcode)
{
        addr=opcode&0x7F;
        if (opcode&0x80) armregs[13]-=(addr<<2);
        else             armregs[13]+=(addr<<2);
}
void TAddISP(unsigned long opcode)
{
        setadd(armregs[13],(opcode&0xFF)<<2,armregs[13]+((opcode&0xFF)<<2));
        armregs[TRD2]=armregs[13]+((opcode&0xFF)<<2);
}
void TAddHigh(unsigned long opcode)
{
        templ=(opcode>>3)&15;
        templ2=TRD;
        if (opcode&0x80) templ2|=8;
        if (templ==15) armregs[templ2]+=(armregs[templ]&~1);
        else           armregs[templ2]+=armregs[templ];
        if (templ2==15)
        {
                armregs[15]+=2;
                refillpipeline();
        }
}

void TCmpImm8(unsigned long opcode)
{
        setsub(armregs[TRD2],opcode&0xFF,armregs[TRD2]-(opcode&0xFF));
}
void TCmpHigh(unsigned long opcode)
{
        templ=(opcode>>3)&15;
        templ2=TRD;
        if (opcode&0x80) templ2|=8;
        setsub(armregs[templ2],armregs[templ],armregs[templ2]-armregs[templ]);
}

void TSubImm(unsigned long opcode)
{
        templ=(opcode>>6)&7;
        setsub(armregs[TRN],templ,armregs[TRN]-templ);
        armregs[TRD]=armregs[TRN]-templ;
}
void TSubImm8(unsigned long opcode)
{
        setsub(armregs[TRD2],opcode&0xFF,armregs[TRD2]-(opcode&0xFF));
        armregs[TRD2]-=(opcode&0xFF);
}
void TSubReg(unsigned long opcode)
{
        setsub(armregs[TRN],armregs[TRM2],armregs[TRN]-armregs[TRM2]);
        armregs[TRD]=armregs[TRN]-armregs[TRM2];
}

void TLdmia(unsigned long opcode)
{
        int c;
        addr=armregs[TRN2];
        for (c=0;c<8;c++)
        {
                if (opcode&(1<<c))
                {
                        armregs[c]=readmeml(addr);
                        cycles--;
                        addr+=4;
                }
        }
        armregs[TRN2]=addr;
}
void TStmia(unsigned long opcode)
{
        int c;
        addr=armregs[TRN2];
        for (c=0;c<8;c++)
        {
                if (opcode&(1<<c))
                {
                        writememl(addr,armregs[c]);
                        cycles--;
                        addr+=4;
                }
        }
        armregs[TRN2]=addr;
}

void TALU(unsigned long opcode)
{
        int cflag=((*pcpsr)&CFLAG)?1:0;
        switch ((opcode>>6)&15)
        {
                case 0x0: /*AND*/
                armregs[TRD]&=armregs[TRM];
                setzn(armregs[TRD]);
                break;
                case 0x1: /*EOR*/
                armregs[TRD]^=armregs[TRM];
                setzn(armregs[TRD]);
                break;
                case 0x2: /*LSL*/
                if (!armregs[TRM]) break;
                armregs[16]&=~CFLAG;
                if (armregs[TRM]>32)
                {
                        armregs[TRD]=0;
                }
                else if (armregs[TRM]==32)
                {
                        if (armregs[TRD]&1) armregs[16]|=CFLAG;
                        armregs[TRD]=0;
                }
                else
                {
                        if ((armregs[TRD]<<(armregs[TRM]-1))&0x80000000) armregs[16]|=CFLAG;
                        armregs[TRD]=armregs[TRD]<<armregs[TRM];
                }
                setzn(armregs[TRD]);
                break;
                case 0x3: /*LSR*/
                if (!armregs[TRM]) break;
                armregs[16]&=~CFLAG;
                if (armregs[TRM]>32)
                {
                        armregs[TRD]=0;
                }
                else if (armregs[TRM]==32)
                {
                        if (armregs[TRD]>>31) armregs[16]|=CFLAG;
                        armregs[TRD]=0;
                }
                else
                {
                        if ((armregs[TRD]>>(armregs[TRM]-1))&1) armregs[16]|=CFLAG;
                        armregs[TRD]=armregs[TRD]>>armregs[TRM];
                }
                setzn(armregs[TRD]);
                break;
                case 0x4: /*ASR*/
                if (!armregs[TRM]) break;
                armregs[16]&=~CFLAG;
                if (armregs[TRM]>=32)
                {
                        armregs[TRD]=(armregs[TRD]>>31)?0xFFFFFFFF:0;
                        if (armregs[TRD]) armregs[16]|=CFLAG;
                }
                else
                {
                        if ((armregs[TRD]>>(armregs[TRM]-1))&1) armregs[16]|=CFLAG;
                        armregs[TRD]=(int)armregs[TRD]>>armregs[TRM];
                }
                setzn(armregs[TRD]);
                break;
                case 0x5: /*ADC*/
                setadd(armregs[TRD],armregs[TRM],armregs[TRD]+armregs[TRM]+cflag);
                armregs[TRD]+=armregs[TRM]+cflag;
                break;
                case 0x6: /*SBC*/
                cflag=(cflag)?0:1;
                setsub(armregs[TRD],armregs[TRM],armregs[TRD]-(armregs[TRM]+cflag));
                armregs[TRD]-=(armregs[TRM]+cflag);
                break;
                case 0x7: /*ROR*/
                if (!(armregs[TRM]&0xFF)) break;
                templ=armregs[TRM]&31;
                armregs[16]&=~CFLAG;
                armregs[TRD]=(armregs[TRD]>>templ)|(armregs[TRD]<<(32-templ));
                if (armregs[TRD]>>31) armregs[16]|=CFLAG;
                setzn(armregs[TRD]);
                break;
                case 0x8: /*TST*/
//                rpclog("TST - %08X %08X %08X\n",armregs[TRM],armregs[TRD],armregs[TRM]&armregs[TRD]);
                setzn(armregs[TRM]&armregs[TRD]);
                break;
                case 0x9: /*NEG*/
                setsub(0,armregs[TRM],0-armregs[TRM]);
                armregs[TRD]=0-armregs[TRM];
                break;
                case 0xA: /*CMP*/
                setsub(armregs[TRD],armregs[TRM],armregs[TRD]-armregs[TRM]);
                break;
                case 0xB: /*CMN*/
                setadd(armregs[TRD],armregs[TRM],armregs[TRD]+armregs[TRM]);
                break;
                case 0xC: /*ORR*/
                armregs[TRD]|=armregs[TRM];
                setzn(armregs[TRD]);
                break;
                case 0xD: /*MUL*/
                armregs[TRD]*=armregs[TRM];
                setzn(armregs[TRD]);
                break;
                case 0xE: /*BIC*/
                armregs[TRD]&=~armregs[TRM];
                setzn(armregs[TRD]);
                break;
                case 0xF: /*MVN*/
                armregs[TRD]=~armregs[TRM];
                setzn(armregs[TRD]);
                break;
                
                default:
                printf("Bad ALU op %04X %01X\n",opcode,(opcode>>6)&15);
                dumpregs();
                exit(-1);
        }
}

#endif
