Example #1
0
void compute_true_and_false_positive_rates(double penality, vector<segment_fits *> noise_fits,
	vector<segment_fits *> query_fits, double & tp, double & fp ){
	//compute false positives
	for (int i = 0 ; i < noise_fits.size(); i++){
		int s 	=  BIC(penality, noise_fits[i]);
		fp+=s;
	}
	//compute true positives
	for (int i = 0 ; i < query_fits.size(); i++){
		int s 	=  BIC(penality, query_fits[i]);
		tp+=s;
	}
}
void GGLAssembler::extract(integer_t& d, int s, int h, int l, int bits)
{
    const int maskLen = h-l;

#ifdef __mips__
    assert(maskLen<=11);
#else
    assert(maskLen<=8);
#endif
    assert(h);
    
#if __ARM_ARCH__ >= 7
    const int mask = (1<<maskLen)-1;
    if ((h == bits) && !l && (s != d.reg)) {
        MOV(AL, 0, d.reg, s);                   // component = packed;
    } else if ((h == bits) && l) {
        MOV(AL, 0, d.reg, reg_imm(s, LSR, l));  // component = packed >> l;
    } else if (!l && isValidImmediate(mask)) {
        AND(AL, 0, d.reg, s, imm(mask));        // component = packed & mask;
    } else if (!l && isValidImmediate(~mask)) {
        BIC(AL, 0, d.reg, s, imm(~mask));       // component = packed & mask;
    } else {
        UBFX(AL, d.reg, s, l, maskLen);         // component = (packed & mask) >> l;
    }
#else
    if (h != bits) {
        const int mask = ((1<<maskLen)-1) << l;
        if (isValidImmediate(mask)) {
            AND(AL, 0, d.reg, s, imm(mask));    // component = packed & mask;
        } else if (isValidImmediate(~mask)) {
            BIC(AL, 0, d.reg, s, imm(~mask));   // component = packed & mask;
        } else {
            MOV(AL, 0, d.reg, reg_imm(s, LSL, 32-h));
            l += 32-h;
            h = 32;
        }
        s = d.reg;
    }
    
    if (l) {
        MOV(AL, 0, d.reg, reg_imm(s, LSR, l));  // component = packed >> l;
        s = d.reg;
    }
    
    if (s != d.reg) {
        MOV(AL, 0, d.reg, s);
    }
#endif

    d.s = maskLen;
}
Example #3
0
int main(int argc, char** argv)
{
    timer *tic, *toc;
    CImage *cimg=NULL;
    Image *mask=NULL;
    Histogram *hist=NULL;

    if (argc != 4) {
        fprintf(stderr,"usage: extrai_bic <image> <mask> <outputfile>\n");
        exit(-1);
    }

    cimg = ReadJPEGFile(argv[1]);
    mask = ReadImage(argv[2]);

    tic = Tic();
    hist = BIC(cimg, mask);
    toc = Toc();
    printf("BIC extracted in %f milliseconds\n\n",CTime(tic, toc));

    FILE *fp;
    fp = fopen(argv[3],"w");
    if (fp == NULL) {
        fprintf(stderr,"Cannot open %s\n",argv[3]);
        exit(-1);
    }

    WriteFHist(hist, fp);

    DestroyCImage(&cimg);
    DestroyHistogram(&hist);
    DestroyImage(&mask);
    fclose(fp);
    return(0);
}
Example #4
0
void JitArm::stmw(UGeckoInstruction inst)
{
	INSTRUCTION_START
	JITDISABLE(bJITLoadStoreOff);
	FALLBACK_IF(!Core::g_CoreStartupParameter.bFastmem);

	u32 a = inst.RA;
	ARMReg rA = gpr.GetReg();
	ARMReg rB = gpr.GetReg();
	ARMReg rC = gpr.GetReg();
	MOVI2R(rA, inst.SIMM_16);
	if (a)
		ADD(rA, rA, gpr.R(a));
	Operand2 mask(2, 1); // ~(Memory::MEMVIEW32_MASK)
	BIC(rA, rA, mask); // 3
	MOVI2R(rB, (u32)Memory::base, false); // 4-5
	ADD(rA, rA, rB); // 6

	for (int i = inst.RD; i < 32; i++)
	{
		ARMReg RX = gpr.R(i);
		REV(rC, RX);
		STR(rC, rA, (i - inst.RD) * 4);
	}
	gpr.Unlock(rA, rB, rC);
}
Example #5
0
void GGLAssembler::build_fog(
                        component_t& temp,      // incomming fragment / output
                        int component,
                        Scratch& regs)
{
   if (mInfo[component].fog) {
        Scratch scratches(registerFile());
        comment("fog");

        integer_t fragment(temp.reg, temp.h, temp.flags);
        if (!(temp.flags & CORRUPTIBLE)) {
            temp.reg = regs.obtain();
            temp.flags |= CORRUPTIBLE;
        }

        integer_t fogColor(scratches.obtain(), 8, CORRUPTIBLE); 
        LDRB(AL, fogColor.reg, mBuilderContext.Rctx,
                immed12_pre(GGL_OFFSETOF(state.fog.color[component])));

        integer_t factor(scratches.obtain(), 16, CORRUPTIBLE);
        CONTEXT_LOAD(factor.reg, generated_vars.f);

        // clamp fog factor (TODO: see if there is a way to guarantee
        // we won't overflow, when setting the iterators)
        BIC(AL, 0, factor.reg, factor.reg, reg_imm(factor.reg, ASR, 31));
        CMP(AL, factor.reg, imm( 0x10000 ));
        MOV(HS, 0, factor.reg, imm( 0x10000 ));

        build_blendFOneMinusF(temp, factor, fragment, fogColor);
    }
}
void JitArm::fcmpu(UGeckoInstruction inst)
{
	INSTRUCTION_START
	JITDISABLE(bJITFloatingPointOff)
	u32 a = inst.FA, b = inst.FB;
	int cr = inst.CRFD;

	ARMReg vA = fpr.R0(a);
	ARMReg vB = fpr.R0(b);
	ARMReg fpscrReg = gpr.GetReg();
	ARMReg crReg = gpr.GetReg();
	Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
	Operand2 LessThan(0x8, 0xA); // 0x8000
	Operand2 GreaterThan(0x4, 0xA); // 0x4000
	Operand2 EqualTo(0x2, 0xA); // 0x2000
	Operand2 NANRes(0x1, 0xA); // 0x1000
	FixupBranch Done1, Done2, Done3;
	LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
	BIC(fpscrReg, fpscrReg, FPRFMask);

	VCMPE(vA, vB);
	VMRS(_PC);
	SetCC(CC_LT);
		ORR(fpscrReg, fpscrReg, LessThan);
		MOV(crReg,  8);
		Done1 = B();
	SetCC(CC_GT);
		ORR(fpscrReg, fpscrReg, GreaterThan);
		MOV(crReg,  4);
		Done2 = B();
	SetCC(CC_EQ);
		ORR(fpscrReg, fpscrReg, EqualTo);
		MOV(crReg,  2);
		Done3 = B();
	SetCC();

	ORR(fpscrReg, fpscrReg, NANRes);
	MOV(crReg,  1);

	VCMPE(vA, vA);
	VMRS(_PC);
	FixupBranch NanA = B_CC(CC_NEQ);
	VCMPE(vB, vB);
	VMRS(_PC);
	FixupBranch NanB = B_CC(CC_NEQ);
	FixupBranch Done4 = B();

	SetJumpTarget(NanA);
	SetJumpTarget(NanB);

	SetFPException(fpscrReg, FPSCR_VXSNAN);

	SetJumpTarget(Done1);
	SetJumpTarget(Done2);
	SetJumpTarget(Done3);
	SetJumpTarget(Done4);
	STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
	STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
	gpr.Unlock(fpscrReg, crReg);
}
Example #7
0
void JitArm::UnsafeStoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset)
{
	// All this gets replaced on backpatch
	Operand2 mask(2, 1); // ~(Memory::MEMVIEW32_MASK)
	BIC(dest, dest, mask); // 1
	MOVI2R(R14, (u32)Memory::base, false); // 2-3
	ADD(dest, dest, R14); // 4
	switch (accessSize)
	{
		case 32:
			REV(value, value); // 5
		break;
		case 16:
			REV16(value, value);
		break;
		case 8:
			NOP(1);
		break;
	}
	switch (accessSize)
	{
		case 32:
			STR(value, dest); // 6
		break;
		case 16:
			STRH(value, dest);
		break;
		case 8:
			STRB(value, dest);
		break;
	}
	NOP(1); // 7
}
Example #8
0
void JitArm::GetCarryAndClear(ARMReg reg)
{
	ARMReg tmp = gpr.GetReg();
	Operand2 mask = Operand2(2, 2); // XER_CA_MASK
	LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
	AND(reg, tmp, mask);
	BIC(tmp, tmp, mask);
	STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
	gpr.Unlock(tmp);
}
Example #9
0
	void Jit::SetCCAndR0ForSafeAddress(MIPSGPReg rs, s16 offset, ARMReg tempReg, bool reverse) {
		SetR0ToEffectiveAddress(rs, offset);

		// There are three valid ranges.  Each one gets a bit.
		const u32 BIT_SCRATCH = 1, BIT_RAM = 2, BIT_VRAM = 4;
		MOVI2R(tempReg, BIT_SCRATCH | BIT_RAM | BIT_VRAM);

		CMP(R0, AssumeMakeOperand2(PSP_GetScratchpadMemoryBase()));
		SetCC(CC_LO);
		BIC(tempReg, tempReg, BIT_SCRATCH);
		SetCC(CC_HS);
		CMP(R0, AssumeMakeOperand2(PSP_GetScratchpadMemoryEnd()));
		BIC(tempReg, tempReg, BIT_SCRATCH);

		// If it was in that range, later compares don't matter.
		CMP(R0, AssumeMakeOperand2(PSP_GetVidMemBase()));
		SetCC(CC_LO);
		BIC(tempReg, tempReg, BIT_VRAM);
		SetCC(CC_HS);
		CMP(R0, AssumeMakeOperand2(PSP_GetVidMemEnd()));
		BIC(tempReg, tempReg, BIT_VRAM);

		CMP(R0, AssumeMakeOperand2(PSP_GetKernelMemoryBase()));
		SetCC(CC_LO);
		BIC(tempReg, tempReg, BIT_RAM);
		SetCC(CC_HS);
		CMP(R0, AssumeMakeOperand2(PSP_GetUserMemoryEnd()));
		BIC(tempReg, tempReg, BIT_RAM);

		// If we left any bit set, the address is OK.
		SetCC(CC_AL);
		CMP(tempReg, 0);
		SetCC(reverse ? CC_EQ : CC_GT);
	}
Example #10
0
void JitArm::ComputeCarry()
{
	ARMReg tmp = gpr.GetReg();
	Operand2 mask = Operand2(2, 2); // XER_CA_MASK
	LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
	SetCC(CC_CS);
	ORR(tmp, tmp, mask);
	SetCC(CC_CC);
	BIC(tmp, tmp, mask);
	SetCC();
	STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
	gpr.Unlock(tmp);
}
Example #11
0
void JitArm::UnsafeLoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offsetReg, s32 offset)
{
	ARMReg rA = gpr.GetReg();
	if (offsetReg == -1)
	{
		MOVI2R(rA, offset, false); // -3
		ADD(addr, addr, rA); // - 1
	}
	else
	{
		NOP(2); // -3, -2
		// offsetReg is preloaded here
		ADD(addr, addr, gpr.R(offsetReg)); // -1
	}

	// All this gets replaced on backpatch
	Operand2 mask(2, 1); // ~(Memory::MEMVIEW32_MASK)
	BIC(addr, addr, mask); // 1
	MOVI2R(rA, (u32)Memory::base, false); // 2-3
	ADD(addr, addr, rA); // 4
	switch (accessSize)
	{
		case 32:
			LDR(dest, addr); // 5
		break;
		case 16:
			LDRH(dest, addr);
		break;
		case 8:
			LDRB(dest, addr);
		break;
	}
	switch (accessSize)
	{
		case 32:
			REV(dest, dest); // 6
		break;
		case 16:
			REV16(dest, dest);
		break;
		case 8:
			NOP(1);
		break;

	}
	NOP(2); // 7-8
	gpr.Unlock(rA);
}
Example #12
0
void Extraction(char *img_path, char *fv_path)
{
  CImage *cimg=NULL;
  Image *mask=NULL;
  Histogram *bic=NULL;

  cimg = ReadCImage(img_path);
  mask = CreateImage(cimg->C[0]->ncols, cimg->C[0]->nrows);

  bic = BIC(cimg, mask);

  WriteFileHistogram(bic,fv_path);
  DestroyHistogram(&bic);
  DestroyImage(&mask);
  DestroyCImage(&cimg);

}
Example #13
0
/*
 * Basic low-level function to reset the PHY.
 * Doesn't incorporate any special-case workarounds.
 *
 * Returns TRUE on success, FALSE if the RESET bit doesn't clear
 */
boolean_t
rge_phy_reset(rge_t *rgep)
{
	uint16_t control;
	uint_t count;

	/*
	 * Set the PHY RESET bit, then wait up to 5 ms for it to self-clear
	 */
	control = rge_mii_get16(rgep, MII_CONTROL);
	rge_mii_put16(rgep, MII_CONTROL, control | MII_CONTROL_RESET);
	for (count = 0; count < 5; count++) {
		drv_usecwait(100);
		control = rge_mii_get16(rgep, MII_CONTROL);
		if (BIC(control, MII_CONTROL_RESET))
			return (B_TRUE);
	}

	RGE_REPORT((rgep, "rge_phy_reset: FAILED, control now 0x%x", control));
	return (B_FALSE);
}
Example #14
0
/*
 * Basic low-level function to reset the PHY.
 * Doesn't incorporate any special-case workarounds.
 *
 * Returns TRUE on success, FALSE if the RESET bit doesn't clear
 */
static boolean_t
bge_phy_reset(bge_t *bgep)
{
	uint16_t control;
	uint_t count;

	BGE_TRACE(("bge_phy_reset($%p)", (void *)bgep));

	ASSERT(mutex_owned(bgep->genlock));

	if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
		drv_usecwait(40);
		/* put PHY into ready state */
		bge_reg_clr32(bgep, MISC_CONFIG_REG, MISC_CONFIG_EPHY_IDDQ);
		(void) bge_reg_get32(bgep, MISC_CONFIG_REG); /* flush */
		drv_usecwait(40);
	}

	/*
	 * Set the PHY RESET bit, then wait up to 5 ms for it to self-clear
	 */
	bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_RESET);
	for (count = 0; ++count < 1000; ) {
		drv_usecwait(5);
		control = bge_mii_get16(bgep, MII_CONTROL);
		if (BIC(control, MII_CONTROL_RESET))
			return (B_TRUE);
	}

	if (DEVICE_5906_SERIES_CHIPSETS(bgep))
		(void) bge_adj_volt_5906(bgep);

	BGE_DEBUG(("bge_phy_reset: FAILED, control now 0x%x", control));

	return (B_FALSE);
}
Example #15
0
int main()
{
	int op;
	uint32_t registro[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	char banderas[4];
	do{
		system("cls");
		printf("seleccione la opcion 1 para mostrar los valores de los registros\n");
		printf("seleccione la opcion 2 para sumar registros \n");
		printf("seleccione la opcion 3 para multiplicacion logica (AND) de registros \n");
		printf("seleccione la opcion 4 para Eor a nivel de bits \n");
		printf("seleccione la opcion 5 para desplazar de un registro a otro \n");
		printf("seleccione la opcion 6 para suma logica (OR) de registro\n");
		printf("seleccione la opcion 7 para ADN sin almacenar, solo modifica banderas \n");
		printf("seleccione la opcion 8 para comparar (SUB sin almacenar), solo modifica banderas\n");
		printf("seleccione la opcion 9 Multiplicacion de registros, solo se alacenan 32 bits menos significativos\n");
		printf("seleccione la opcion 10 AND sin almacenacmiento, solo modifica banderas\n");
		printf("seleccione la opcion 11 para  LSL desplazamiento logico a la izquierda \n");
		printf("seleccione la opcion 12 para  LSR desplazamiento logico a la derecha \n");
		printf("seleccione la opcion 13 para  ROR rotacion a la derecha \n");
		printf("seleccione la opcion 14 para  ASR desplazamiento aritmetico a la derecha \n");
		printf("seleccione la opcion 15 para  BIC Realiza una AND de un registro con otro negado \n");
		printf("seleccione la opcion 16 para  MUN guarda en un registro la negacion de otro\n");
		printf("seleccione la opcion 17 para  RSB niega un valor de registro\n");
		printf("seleccione la opcion 18 para  NOP da un retardo de un ciclo de reloj (no hace nada) \n");
		printf("seleccione la opcion 19 para  REV toma grupos de 8 bits y los desplaza \n");
		printf("seleccione la opcion 20 para  REVIG toma grupos de 16 bits y los agrupa en grupos de dos bytes\n");
		printf("seleccione la opcion 21 para  REVSH extencion con signo\n\n");
		
		scanf("%d",&op);
		
		system("cls");
		switch(op){		

			case 1:			
				//mostrar_valores(registro);			
			break;
			
			case 2:			
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese el valor del segundo registro:\n");
				scanf("%d",&registro[2]);
				
				ADD(registro,&registro[0],registro[1],registro[2],&banderas[0]);
				
				printf("%d valor del resultado \n",registro[0]);
				printf("%d valor del resultado bandera n \n",banderas[N]);
				printf("%d valor del resultado bandera z \n",banderas[Z]);
				printf("%d valor del resultado bandera c \n",banderas[C]);
				printf("%d valor del resultado bandera v \n",banderas[V]);
			break;
			
			case 3:				
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese el valor del segundo registro:\n");
				scanf("%d",&registro[2]);
					
				AND(registro,&registro[0],registro[1],registro[2],&banderas[0]);
				
				printf("%d valor del resultado \n",registro[0]);
				printf("%d valor del resultado bandera n \n",banderas[N]);
				printf("%d valor del resultado bandera z \n",banderas[Z]);
				printf("%d valor del resultado bandera c \n",banderas[C]);
				printf("%d valor del resultado bandera v \n",banderas[V]);
			break;
			
			case 4:
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese el valor del segundo registro:\n");
				scanf("%d",&registro[2]);
				
				EOR(registro,&registro[0],registro[1],registro[2],&banderas[0]);
				
				printf("%d valor del resultado \n",registro[0]);
				printf("%d valor del resultado bandera n \n",banderas[N]);
				printf("%d valor del resultado bandera z \n",banderas[Z]);
				printf("%d valor del resultado bandera c \n",banderas[C]);
				printf("%d valor del resultado bandera v \n",banderas[V]);
			break;
			
			case 5:
				printf("ingrese el valor del registro origen:\n");
				scanf("%d",&registro[1]);
				
				MOV(registro,&registro[0],registro[1],banderas);
				
				printf("%d valor del resultado \n",registro[0]);
			break;
			
			case 7:
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese el valor del segundo registro:\n");
				scanf("%d",&registro[2]);
				
				CMN(registro,registro[1],registro[2],&banderas[0]);
				
				printf("%d valor del resultado \n",registro[0]);
				printf("%d valor del resultado bandera n \n",banderas[N]);
				printf("%d valor del resultado bandera z \n",banderas[Z]);
				printf("%d valor del resultado bandera c \n",banderas[C]);
				printf("%d valor del resultado bandera v \n",banderas[V]);
			break;
			
			case 8:
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese el valor del segundo registro:\n");
				scanf("%d",&registro[2]);
				
				CMP(registro,registro[1],registro[2],&banderas[0]);
				
				printf("%d valor del resultado \n",registro[0]);
				printf("%d valor del resultado bandera n \n",banderas[N]);
				printf("%d valor del resultado bandera z \n",banderas[Z]);
				printf("%d valor del resultado bandera c \n",banderas[C]);
				printf("%d valor del resultado bandera v \n",banderas[V]);
			break;
			
			case 9:			
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese el valor del segundo registro:\n");
				scanf("%d",&registro[2]);
				
				MUL(registro,&registro[0],registro[1],registro[2],&banderas[0]);
				
				printf("%d valor del resultado \n",registro[0]);
				printf("%d valor del resultado bandera n \n",banderas[N]);
				printf("%d valor del resultado bandera z \n",banderas[Z]);
				printf("%d valor del resultado bandera c \n",banderas[C]);
				printf("%d valor del resultado bandera v \n",banderas[V]);
			break;
			
			case 10:			
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese el valor del segundo registro:\n");
				scanf("%d",&registro[2]);
				
				TST(registro,registro[1],registro[2],&banderas[0]);
				
				printf("%d valor del resultado \n",registro[0]);
				printf("%d valor del resultado bandera n \n",banderas[N]);
				printf("%d valor del resultado bandera z \n",banderas[Z]);
				printf("%d valor del resultado bandera c \n",banderas[C]);
				printf("%d valor del resultado bandera v \n",banderas[V]);
			break;
			
			case 11:			
				printf("ingrese el valor del registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese el numero de desplazamientos:\n");
				scanf("%d",&registro[2]);
				
				LSL(registro,&registro[0],registro[1],registro[2],banderas);
				
				printf("%d valor del resultado \n",registro[0]);
			break;
			
			case 12:
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese elnumero de desplazamientos:\n");
				scanf("%d",&registro[2]);
				
				LSR(registro,&registro[0],registro[1],registro[2],banderas);
				
				printf("%d valor del resultado \n",registro[0]);
			break;			
			
			case 13:			
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese elnumero de desplazamientos:\n");
				scanf("%d",&registro[2]);
				
				ROR(registro,&registro[0],registro[1],registro[2],banderas);
				
				printf("%d valor del resultado \n",registro[0]);
			break;
			
			case 14:			
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[1]);
				printf("ingrese elnumero de desplazamientos:\n");
				scanf("%d",&registro[2]);
				
				ASR(registro,&registro[0],registro[1],registro[2],banderas);
				
				printf("%d valor del resultado \n",registro[0]);
			break;

			case 15:			
				printf("ingrese el valor del primer registro:\n");
				scanf("%d",&registro[0]);
				printf("ingrese el valor del segundo registro:\n");
				scanf("%d",&registro[1]);
				
				BIC(registro,&registro[0],registro[1],banderas);
				
				printf("%d valor del resultado \n",registro[0]);
			break;
			
			case 16:			
				printf("ingrese un valor del registro origen\n");
				scanf("%d",&registro[1]);
				
				MVN(registro,&registro[0],registro[1],banderas);
				
				printf("%d valor del resultado \n",registro[0]);
			break;
			
			case 17:			
				printf("ingrese un valor de registro\n");
				scanf("%d",&registro[1]);	
				
				RSB(registro,&registro[0],registro[1],0,banderas);
				
				printf("%d valor del resultado \n",registro[0]);
			break;
			
			case 18:			
				NOP(registro);
			break;
			
			case 19:			
				printf("ingrese un valor de registro \n");
				scanf("%d",&registro[0]);
				
				REV(registro,&registro[0]);
				
				printf("%d valor del resultado \n",registro[0]);
			break;
			
			case 20:			
				printf("ingrese un valor de registro \n");
				scanf("%d",&registro[0]);
				
				REVIG(registro,&registro[0]);
				
				printf("%d valor del resultado \n",registro[0]);
			break;
			
			case 21:			
				printf("ingrese un valor de registro \n");
				scanf("%d",&registro[0]);
				
				REVSH(registro,&registro[0]);
				
				printf("%d valor del resultado \n",registro[0]);
			break;	
			
			default:
				printf("Opcion invalida\n\n");
			break;
		}
		printf("\nDesea realizar otra operacion?\n<1>-si\n<0>-no\n");
		scanf("%d",&op);
		system("cls");
		}while(op);
		return 0;
}
Example #16
0
void Jit::Comp_mxc1(u32 op)
{
	CONDITIONAL_DISABLE;

	int fs = _FS;
	int rt = _RT;

	switch((op >> 21) & 0x1f) 
	{
	case 0: // R(rt) = FI(fs); break; //mfc1
		// Let's just go through RAM for now.
		fpr.FlushR(fs);
		gpr.MapReg(rt, MAP_DIRTY | MAP_NOINIT);
		LDR(gpr.R(rt), CTXREG, fpr.GetMipsRegOffset(fs));
		return;

	case 2: //cfc1
		if (fs == 31)
		{
			gpr.MapReg(rt, MAP_DIRTY | MAP_NOINIT);
			LDR(R0, CTXREG, offsetof(MIPSState, fpcond));
			AND(R0,R0, Operand2(1)); // Just in case
			LDR(gpr.R(rt), CTXREG, offsetof(MIPSState, fcr31));
			BIC(gpr.R(rt), gpr.R(rt), Operand2(0x1 << 23));
			ORR(gpr.R(rt), gpr.R(rt), Operand2(R0, ST_LSL, 23));
		}
		else if (fs == 0)
		{
			gpr.MapReg(rt, MAP_DIRTY | MAP_NOINIT);
			LDR(gpr.R(rt), CTXREG, offsetof(MIPSState, fcr0));
		}
		return;

	case 4: //FI(fs) = R(rt);	break; //mtc1
		// Let's just go through RAM for now.
		gpr.FlushR(rt);
		fpr.MapReg(fs, MAP_DIRTY | MAP_NOINIT);
		VLDR(fpr.R(fs), CTXREG, gpr.GetMipsRegOffset(rt));
		return;

	case 6: //ctc1
		if (fs == 31)
		{
			gpr.MapReg(rt, 0);
			// Hardware rounding method.
			// Left here in case it is faster than conditional method.
			/*
			AND(R0, gpr.R(rt), Operand2(3));
			// MIPS Rounding Mode <-> ARM Rounding Mode
			//         0, 1, 2, 3 <->  0, 3, 1, 2
			CMP(R0, Operand2(1));
			SetCC(CC_EQ); ADD(R0, R0, Operand2(2));
			SetCC(CC_GT); SUB(R0, R0, Operand2(1));
			SetCC(CC_AL);

			// Load and Store RM to FPSCR
			VMRS(R1);
			BIC(R1, R1, Operand2(0x3 << 22));
			ORR(R1, R1, Operand2(R0, ST_LSL, 22));
			VMSR(R1);
			*/
			// Update MIPS state
			STR(gpr.R(rt), CTXREG, offsetof(MIPSState, fcr31));
			MOV(R0, Operand2(gpr.R(rt), ST_LSR, 23));
			AND(R0, R0, Operand2(1));
			STR(R0, CTXREG, offsetof(MIPSState, fpcond));
		}
		return;
	}
}
Example #17
0
void JitArmILAsmRoutineManager::Generate()
{
	enterCode = GetCodePtr();
	PUSH(9, R4, R5, R6, R7, R8, R9, R10, R11, _LR);
	// Take care to 8-byte align stack for function calls.
	// We are misaligned here because of an odd number of args for PUSH.
	// It's not like x86 where you need to account for an extra 4 bytes
	// consumed by CALL.
	SUB(_SP, _SP, 4);

	MOVI2R(R0, (u32)&CoreTiming::downcount);
	MOVI2R(R9, (u32)&PowerPC::ppcState.spr[0]);

	FixupBranch skipToRealDispatcher = B();
	dispatcher = GetCodePtr();
		printf("ILDispatcher is %p\n", dispatcher);

		// Downcount Check
		// The result of slice decrementation should be in flags if somebody jumped here
		// IMPORTANT - We jump on negative, not carry!!!
		FixupBranch bail = B_CC(CC_MI);

		SetJumpTarget(skipToRealDispatcher);
		dispatcherNoCheck = GetCodePtr();

		// This block of code gets the address of the compiled block of code
		// It runs though to the compiling portion if it isn't found
			LDR(R12, R9, PPCSTATE_OFF(pc));// Load the current PC into R12

			Operand2 iCacheMask = Operand2(0xE, 2); // JIT_ICACHE_MASK
			BIC(R12, R12, iCacheMask); // R12 contains PC & JIT_ICACHE_MASK here.

			MOVI2R(R14, (u32)jit->GetBlockCache()->iCache);

			LDR(R12, R14, R12); // R12 contains iCache[PC & JIT_ICACHE_MASK] here
			// R12 Confirmed this is the correct iCache Location loaded.
			TST(R12, 0x80); // Test  to see if it is a JIT block.

			SetCC(CC_EQ);
				// Success, it is our Jitblock.
				MOVI2R(R14, (u32)jit->GetBlockCache()->GetCodePointers());
				// LDR R14 right here to get CodePointers()[0] pointer.
				LSL(R12, R12, 2); // Multiply by four because address locations are u32 in size
				LDR(R14, R14, R12); // Load the block address in to R14

				B(R14);
				// No need to jump anywhere after here, the block will go back to dispatcher start
			SetCC();

		// If we get to this point, that means that we don't have the block cached to execute
		// So call ArmJit to compile the block and then execute it.
		MOVI2R(R14, (u32)&Jit);
		BL(R14);

		B(dispatcherNoCheck);

		// fpException()
		// Floating Point Exception Check, Jumped to if false
		fpException = GetCodePtr();
			LDR(R0, R9, PPCSTATE_OFF(Exceptions));
			ORR(R0, R0, EXCEPTION_FPU_UNAVAILABLE);
			STR(R0, R9, PPCSTATE_OFF(Exceptions));
				QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions);
			LDR(R0, R9, PPCSTATE_OFF(npc));
			STR(R0, R9, PPCSTATE_OFF(pc));
		B(dispatcher);

		SetJumpTarget(bail);
		doTiming = GetCodePtr();
		// XXX: In JIT64, Advance() gets called /after/ the exception checking
		// once it jumps back to the start of outerLoop
		QuickCallFunction(R14, (void*)&CoreTiming::Advance);

		// Does exception checking
		testExceptions = GetCodePtr();
			LDR(R0, R9, PPCSTATE_OFF(pc));
			STR(R0, R9, PPCSTATE_OFF(npc));
				QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions);
			LDR(R0, R9, PPCSTATE_OFF(npc));
			STR(R0, R9, PPCSTATE_OFF(pc));
		// Check the state pointer to see if we are exiting
		// Gets checked on every exception check
			MOVI2R(R0, (u32)PowerPC::GetStatePtr());
			MVN(R1, 0);
			LDR(R0, R0);
			TST(R0, R1);
			FixupBranch Exit = B_CC(CC_NEQ);

	B(dispatcher);

	SetJumpTarget(Exit);

	ADD(_SP, _SP, 4);

	POP(9, R4, R5, R6, R7, R8, R9, R10, R11, _PC);  // Returns

	GenerateCommon();

	FlushIcache();
}
void JitArm::fctiwx(UGeckoInstruction inst)
{
	INSTRUCTION_START
	JITDISABLE(bJITFloatingPointOff)
	u32 b = inst.FB;
	u32 d = inst.FD;

	ARMReg vB = fpr.R0(b);
	ARMReg vD = fpr.R0(d);
	ARMReg V0 = fpr.GetReg();
	ARMReg V1 = fpr.GetReg();
	ARMReg V2 = fpr.GetReg();

	ARMReg rA = gpr.GetReg();
	ARMReg fpscrReg = gpr.GetReg();

	FixupBranch DoneMax, DoneMin;
	LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
	MOVI2R(rA, (u32)minmaxFloat);

	// Check if greater than max float
	{
		VLDR(V0, rA, 8); // Load Max
		VCMPE(vB, V0);
		VMRS(_PC); // Loads in to APSR
		FixupBranch noException = B_CC(CC_LE);
		VMOV(vD, V0); // Set to max
		SetFPException(fpscrReg, FPSCR_VXCVI);
		DoneMax = B();
		SetJumpTarget(noException);
	}
	// Check if less than min float
	{
		VLDR(V0, rA, 0);
		VCMPE(vB, V0);
		VMRS(_PC);
		FixupBranch noException = B_CC(CC_GE);
		VMOV(vD, V0);
		SetFPException(fpscrReg, FPSCR_VXCVI);
		DoneMin = B();
		SetJumpTarget(noException);
	}
	// Within ranges, convert to integer
	// Set rounding mode first
	// PPC <-> ARM rounding modes
	// 0, 1, 2, 3 <-> 0, 3, 1, 2
	ARMReg rB = gpr.GetReg();
	VMRS(rA);
	// Bits 22-23
	BIC(rA, rA, Operand2(3, 5));

	LDR(rB, R9, PPCSTATE_OFF(fpscr));
	AND(rB, rB, 0x3); // Get the FPSCR rounding bits
	CMP(rB, 1);
	SetCC(CC_EQ); // zero
		ORR(rA, rA, Operand2(3, 5));
	SetCC(CC_NEQ);
		CMP(rB, 2); // +inf
		SetCC(CC_EQ);
			ORR(rA, rA, Operand2(1, 5));
		SetCC(CC_NEQ);
			CMP(rB, 3); // -inf
			SetCC(CC_EQ);
				ORR(rA, rA, Operand2(2, 5));
	SetCC();
	VMSR(rA);
	ORR(rA, rA, Operand2(3, 5));
	VCVT(vD, vB, TO_INT | IS_SIGNED);
	VMSR(rA);
	gpr.Unlock(rB);
	VCMPE(vD, vB);
	VMRS(_PC);

	SetCC(CC_EQ);
		BIC(fpscrReg, fpscrReg, FRFIMask);
		FixupBranch DoneEqual = B();
	SetCC();
	SetFPException(fpscrReg, FPSCR_XX);
	ORR(fpscrReg, fpscrReg, FIMask);
	VABS(V1, vB);
	VABS(V2, vD);
	VCMPE(V2, V1);
	VMRS(_PC);
	SetCC(CC_GT);
		ORR(fpscrReg, fpscrReg, FRMask);
	SetCC();
	SetJumpTarget(DoneEqual);

	SetJumpTarget(DoneMax);
	SetJumpTarget(DoneMin);

	MOVI2R(rA, (u32)&doublenum);
	VLDR(V0, rA, 0);
	NEONXEmitter nemit(this);
	nemit.VORR(vD, vD, V0);

	if (inst.Rc) Helper_UpdateCR1(fpscrReg, rA);

	STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
	gpr.Unlock(rA);
	gpr.Unlock(fpscrReg);
	fpr.Unlock(V0);
	fpr.Unlock(V1);
	fpr.Unlock(V2);
}
void JitArm::fctiwzx(UGeckoInstruction inst)
{
	INSTRUCTION_START
	JITDISABLE(bJITFloatingPointOff)
	u32 b = inst.FB;
	u32 d = inst.FD;

	ARMReg vB = fpr.R0(b);
	ARMReg vD = fpr.R0(d);
	ARMReg V0 = fpr.GetReg();
	ARMReg V1 = fpr.GetReg();
	ARMReg V2 = fpr.GetReg();

	ARMReg rA = gpr.GetReg();
	ARMReg fpscrReg = gpr.GetReg();

	FixupBranch DoneMax, DoneMin;
	LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
	MOVI2R(rA, (u32)minmaxFloat);

	// Check if greater than max float
	{
		VLDR(V0, rA, 8); // Load Max
		VCMPE(vB, V0);
		VMRS(_PC); // Loads in to APSR
		FixupBranch noException = B_CC(CC_LE);
		VMOV(vD, V0); // Set to max
		SetFPException(fpscrReg, FPSCR_VXCVI);
		DoneMax = B();
		SetJumpTarget(noException);
	}
	// Check if less than min float
	{
		VLDR(V0, rA, 0);
		VCMPE(vB, V0);
		VMRS(_PC);
		FixupBranch noException = B_CC(CC_GE);
		VMOV(vD, V0);
		SetFPException(fpscrReg, FPSCR_VXCVI);
		DoneMin = B();
		SetJumpTarget(noException);
	}
	// Within ranges, convert to integer
	VCVT(vD, vB, TO_INT | IS_SIGNED | ROUND_TO_ZERO);
	VCMPE(vD, vB);
	VMRS(_PC);

	SetCC(CC_EQ);
		BIC(fpscrReg, fpscrReg, FRFIMask);
		FixupBranch DoneEqual = B();
	SetCC();
	SetFPException(fpscrReg, FPSCR_XX);
	ORR(fpscrReg, fpscrReg, FIMask);
	VABS(V1, vB);
	VABS(V2, vD);
	VCMPE(V2, V1);
	VMRS(_PC);
	SetCC(CC_GT);
		ORR(fpscrReg, fpscrReg, FRMask);
	SetCC();
	SetJumpTarget(DoneEqual);

	SetJumpTarget(DoneMax);
	SetJumpTarget(DoneMin);

	MOVI2R(rA, (u32)&doublenum);
	VLDR(V0, rA, 0);
	NEONXEmitter nemit(this);
	nemit.VORR(vD, vD, V0);

	if (inst.Rc) Helper_UpdateCR1(fpscrReg, rA);

	STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
	gpr.Unlock(rA);
	gpr.Unlock(fpscrReg);
	fpr.Unlock(V0);
	fpr.Unlock(V1);
	fpr.Unlock(V2);
}
Example #20
0
static boolean_t
bge_check_serdes(bge_t *bgep, boolean_t recheck)
{
	uint32_t emac_status;
	uint32_t tx_status;
	uint32_t lpadv;
	boolean_t linkup;
	boolean_t linkup_old = bgep->param_link_up;

	for (;;) {
		/*
		 * Step 10: BCM5714S, BCM5715S only
		 * Don't call function bge_autoneg_serdes() as
		 * RX_1000BASEX_AUTONEG_REG (0x0448) is not applicable
		 * to BCM5705, BCM5788, BCM5721, BCM5751, BCM5752,
		 * BCM5714, and BCM5715 devices.
		 */
		if (DEVICE_5714_SERIES_CHIPSETS(bgep)) {
			tx_status = bge_reg_get32(bgep,
			    TRANSMIT_MAC_STATUS_REG);
			linkup = BIS(tx_status, TRANSMIT_STATUS_LINK_UP);
			emac_status = bge_reg_get32(bgep,
			    ETHERNET_MAC_STATUS_REG);
			bgep->serdes_status = emac_status;
			if ((linkup && linkup_old) ||
			    (!linkup && !linkup_old)) {
				emac_status &= ~ETHERNET_STATUS_LINK_CHANGED;
				emac_status &= ~ETHERNET_STATUS_RECEIVING_CFG;
				break;
			}
			emac_status |= ETHERNET_STATUS_LINK_CHANGED;
			emac_status |= ETHERNET_STATUS_RECEIVING_CFG;
			if (linkup)
				linkup_old = B_TRUE;
			else
				linkup_old = B_FALSE;
			recheck = B_TRUE;
		} else {
			/*
			 * Step 10: others
			 * read & clear the main (Ethernet) MAC status
			 * (the relevant bits of this are write-one-to-clear).
			 */
			emac_status = bge_reg_get32(bgep,
			    ETHERNET_MAC_STATUS_REG);
			bge_reg_put32(bgep,
			    ETHERNET_MAC_STATUS_REG, emac_status);

			BGE_DEBUG(("bge_check_serdes: link %d/%s, "
			    "MAC status 0x%x (was 0x%x)",
			    bgep->link_state, UPORDOWN(bgep->param_link_up),
			    emac_status, bgep->serdes_status));

			/*
			 * We will only consider the link UP if all the readings
			 * are consistent and give meaningful results ...
			 */
			bgep->serdes_status = emac_status;
			linkup = BIS(emac_status,
			    ETHERNET_STATUS_SIGNAL_DETECT);
			linkup &= BIS(emac_status, ETHERNET_STATUS_PCS_SYNCHED);

			/*
			 * Now some fiddling with the interpretation:
			 *	if there's been an error at the PCS level, treat
			 *	it as a link change (the h/w doesn't do this)
			 *
			 *	if there's been a change, but it's only a PCS
			 *	sync change (not a config change), AND the link
			 *	already was & is still UP, then ignore the
			 *	change
			 */
			if (BIS(emac_status, ETHERNET_STATUS_PCS_ERROR))
				emac_status |= ETHERNET_STATUS_LINK_CHANGED;
			else if (BIC(emac_status, ETHERNET_STATUS_CFG_CHANGED))
				if (bgep->param_link_up && linkup)
					emac_status &=
					    ~ETHERNET_STATUS_LINK_CHANGED;

			BGE_DEBUG(("bge_check_serdes: status 0x%x => 0x%x %s",
			    bgep->serdes_status, emac_status,
			    UPORDOWN(linkup)));

			/*
			 * If we're receiving configs, run the autoneg protocol
			 */
			if (linkup && BIS(emac_status,
			    ETHERNET_STATUS_RECEIVING_CFG))
				bge_autoneg_serdes(bgep);

			/*
			 * If the SerDes status hasn't changed, we're done ...
			 */
			if (BIC(emac_status, ETHERNET_STATUS_LINK_CHANGED))
				break;

			/*
			 * Go round again until we no longer see a change ...
			 */
			recheck = B_TRUE;
		}
	}

	/*
	 * If we're not forcing a recheck (i.e. the link state was already
	 * known), and we didn't see the hardware flag a change, there's
	 * no more to do (and we tell the caller nothing happened).
	 */
	if (!recheck)
		return (B_FALSE);

	/*
	 * Don't resolve autoneg until we're no longer receiving configs
	 */
	if (linkup && BIS(emac_status, ETHERNET_STATUS_RECEIVING_CFG))
		return (B_FALSE);

	/*
	 * Assume very little ...
	 */
	bgep->param_lp_autoneg = B_FALSE;
	bgep->param_lp_1000fdx = B_FALSE;
	bgep->param_lp_1000hdx = B_FALSE;
	bgep->param_lp_100fdx = B_FALSE;
	bgep->param_lp_100hdx = B_FALSE;
	bgep->param_lp_10fdx = B_FALSE;
	bgep->param_lp_10hdx = B_FALSE;
	bgep->param_lp_pause = B_FALSE;
	bgep->param_lp_asym_pause = B_FALSE;
	bgep->param_link_autoneg = B_FALSE;
	bgep->param_link_tx_pause = B_FALSE;
	if (bgep->param_adv_autoneg)
		bgep->param_link_rx_pause = B_FALSE;
	else
		bgep->param_link_rx_pause = bgep->param_adv_pause;

	/*
	 * Discover all the link partner's abilities.
	 */
	lpadv = bgep->serdes_lpadv;
	if (lpadv != 0 && BIC(lpadv, AUTONEG_CODE_FAULT_MASK)) {
		/*
		 * No fault, so derive partner's capabilities
		 */
		bgep->param_lp_autoneg = B_TRUE;
		bgep->param_lp_1000fdx = BIS(lpadv, AUTONEG_CODE_FULL_DUPLEX);
		bgep->param_lp_1000hdx = BIS(lpadv, AUTONEG_CODE_HALF_DUPLEX);
		bgep->param_lp_pause = BIS(lpadv, AUTONEG_CODE_PAUSE);
		bgep->param_lp_asym_pause = BIS(lpadv, AUTONEG_CODE_ASYM_PAUSE);

		/*
		 * Pause direction resolution
		 */
		bgep->param_link_autoneg = B_TRUE;
		if (bgep->param_adv_pause &&
		    bgep->param_lp_pause) {
			bgep->param_link_tx_pause = B_TRUE;
			bgep->param_link_rx_pause = B_TRUE;
		}
		if (bgep->param_adv_asym_pause &&
		    bgep->param_lp_asym_pause) {
			if (bgep->param_adv_pause)
				bgep->param_link_rx_pause = B_TRUE;
			if (bgep->param_lp_pause)
				bgep->param_link_tx_pause = B_TRUE;
		}
	}

	/*
	 * Step 12: update ndd-visible state parameters, BUT!
	 * we don't transfer the new state to <link_state> just yet;
	 * instead we mark the <link_state> as UNKNOWN, and our caller
	 * will resolve it once the status has stopped changing and
	 * been stable for several seconds.
	 */
	BGE_DEBUG(("bge_check_serdes: link was %s speed %d duplex %d",
	    UPORDOWN(bgep->param_link_up),
	    bgep->param_link_speed,
	    bgep->param_link_duplex));

	if (linkup) {
		bgep->param_link_up = B_TRUE;
		bgep->param_link_speed = 1000;
		if (bgep->param_adv_1000fdx)
			bgep->param_link_duplex = LINK_DUPLEX_FULL;
		else
			bgep->param_link_duplex = LINK_DUPLEX_HALF;
		if (bgep->param_lp_autoneg && !bgep->param_lp_1000fdx)
			bgep->param_link_duplex = LINK_DUPLEX_HALF;
	} else {
		bgep->param_link_up = B_FALSE;
		bgep->param_link_speed = 0;
		bgep->param_link_duplex = LINK_DUPLEX_UNKNOWN;
	}
	bgep->link_state = LINK_STATE_UNKNOWN;

	BGE_DEBUG(("bge_check_serdes: link now %s speed %d duplex %d",
	    UPORDOWN(bgep->param_link_up),
	    bgep->param_link_speed,
	    bgep->param_link_duplex));

	return (B_TRUE);
}
void JitArm::lfXX(UGeckoInstruction inst)
{
	INSTRUCTION_START
	JITDISABLE(bJITLoadStoreFloatingOff);

	ARMReg rA = gpr.GetReg();
	ARMReg rB = gpr.GetReg();
	ARMReg RA;

	u32 a = inst.RA, b = inst.RB;

	s32 offset = inst.SIMM_16;
	bool single = false;
	bool update = false;
	bool zeroA = false;
	s32 offsetReg = -1;

	switch (inst.OPCD)
	{
		case 31:
			switch (inst.SUBOP10)
			{
				case 567: // lfsux
					single = true;
					update = true;
					offsetReg = b;
				break;
				case 535: // lfsx
					single = true;
					zeroA = true;
					offsetReg = b;
				break;
				case 631: // lfdux
					update = true;
					offsetReg = b;
				break;
				case 599: // lfdx
					zeroA = true;
					offsetReg = b;
				break;
			}
		break;
		case 49: // lfsu
			update = true;
			single = true;
		break;
		case 48: // lfs
			single = true;
			zeroA = true;
		break;
		case 51: // lfdu
			update = true;
		break;
		case 50: // lfd
			zeroA = true;
		break;
	}

	ARMReg v0 = fpr.R0(inst.FD), v1;
	if (single)
		v1 = fpr.R1(inst.FD);

	if (update)
	{
		RA = gpr.R(a);
		// Update path /always/ uses RA
		if (offsetReg == -1) // uses SIMM_16
		{
			MOVI2R(rB, offset);
			ADD(rB, rB, RA);
		}
		else
		{
			ADD(rB, gpr.R(offsetReg), RA);
		}
	}
	else
	{
		if (zeroA)
		{
			if (offsetReg == -1)
			{
				if (a)
				{
					RA = gpr.R(a);
					MOVI2R(rB, offset);
					ADD(rB, rB, RA);
				}
				else
				{
					MOVI2R(rB, (u32)offset);
				}
			}
			else
			{
				ARMReg RB = gpr.R(offsetReg);
				if (a)
				{
					RA = gpr.R(a);
					ADD(rB, RB, RA);
				}
				else
				{
					MOV(rB, RB);
				}
			}
		}
	}
	LDR(rA, R9, PPCSTATE_OFF(Exceptions));
	CMP(rA, EXCEPTION_DSI);
	FixupBranch DoNotLoad = B_CC(CC_EQ);

	if (update)
		MOV(RA, rB);

	if (Core::g_CoreStartupParameter.bFastmem)
	{
		Operand2 mask(2, 1); // ~(Memory::MEMVIEW32_MASK)
		BIC(rB, rB, mask); // 1
		MOVI2R(rA, (u32)Memory::base, false); // 2-3
		ADD(rB, rB, rA); // 4

		NEONXEmitter nemit(this);
		if (single)
		{
			VLDR(S0, rB, 0);
			nemit.VREV32(I_8, D0, D0); // Byte swap to result
			VCVT(v0, S0, 0);
			VCVT(v1, S0, 0);
		}
		else
		{
			VLDR(v0, rB, 0);
			nemit.VREV64(I_8, v0, v0); // Byte swap to result
		}
	}
	else
	{
		PUSH(4, R0, R1, R2, R3);
		MOV(R0, rB);
		if (single)
		{
			MOVI2R(rA, (u32)&Memory::Read_U32);
			BL(rA);

			VMOV(S0, R0);

			VCVT(v0, S0, 0);
			VCVT(v1, S0, 0);
		}
		else
		{
			MOVI2R(rA, (u32)&Memory::Read_F64);
			BL(rA);

#if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1
			VMOV(v0, R0);
#else
			VMOV(v0, D0);
#endif
		}
		POP(4, R0, R1, R2, R3);
	}
	gpr.Unlock(rA, rB);
	SetJumpTarget(DoNotLoad);
}
void JitArm::stfXX(UGeckoInstruction inst)
{
	INSTRUCTION_START
	JITDISABLE(bJITLoadStoreFloatingOff);

	ARMReg rA = gpr.GetReg();
	ARMReg rB = gpr.GetReg();
	ARMReg RA;

	u32 a = inst.RA, b = inst.RB;

	s32 offset = inst.SIMM_16;
	bool single = false;
	bool update = false;
	bool zeroA = false;
	s32 offsetReg = -1;

	switch (inst.OPCD)
	{
		case 31:
			switch (inst.SUBOP10)
			{
				case 663: // stfsx
					single = true;
					zeroA = true;
					offsetReg = b;
				break;
				case 695: // stfsux
					single = true;
					offsetReg = b;
				break;
				case 727: // stfdx
					zeroA = true;
					offsetReg = b;
				break;
				case 759: // stfdux
					update = true;
					offsetReg = b;
				break;
			}
		break;
		case 53: // stfsu
			update = true;
			single = true;
		break;
		case 52: // stfs
			single = true;
			zeroA = true;
		break;
		case 55: // stfdu
			update = true;
		break;
		case 54: // stfd
			zeroA = true;
		break;
	}

	ARMReg v0 = fpr.R0(inst.FS);

	if (update)
	{
		RA = gpr.R(a);
		// Update path /always/ uses RA
		if (offsetReg == -1) // uses SIMM_16
		{
			MOVI2R(rB, offset);
			ADD(rB, rB, RA);
		}
		else
		{
			ADD(rB, gpr.R(offsetReg), RA);
		}
	}
	else
	{
		if (zeroA)
		{
			if (offsetReg == -1)
			{
				if (a)
				{
					RA = gpr.R(a);
					MOVI2R(rB, offset);
					ADD(rB, rB, RA);
				}
				else
				{
					MOVI2R(rB, (u32)offset);
				}
			}
			else
			{
				ARMReg RB = gpr.R(offsetReg);
				if (a)
				{
					RA = gpr.R(a);
					ADD(rB, RB, RA);
				}
				else
				{
					MOV(rB, RB);
				}
			}
		}
	}

	if (update)
	{
		LDR(rA, R9, PPCSTATE_OFF(Exceptions));
		CMP(rA, EXCEPTION_DSI);

		SetCC(CC_NEQ);
		MOV(RA, rB);
		SetCC();
	}
	if (Core::g_CoreStartupParameter.bFastmem)
	{
		Operand2 mask(2, 1); // ~(Memory::MEMVIEW32_MASK)
		BIC(rB, rB, mask); // 1
		MOVI2R(rA, (u32)Memory::base, false); // 2-3
		ADD(rB, rB, rA); // 4

		NEONXEmitter nemit(this);
		if (single)
		{
			VCVT(S0, v0, 0);
			nemit.VREV32(I_8, D0, D0);
			VSTR(S0, rB, 0);
		}
		else
		{
			nemit.VREV64(I_8, D0, v0);
			VSTR(D0, rB, 0);
		}
	}
	else
	{
		PUSH(4, R0, R1, R2, R3);
		if (single)
		{
			MOVI2R(rA, (u32)&Memory::Write_U32);
			VCVT(S0, v0, 0);
			VMOV(R0, S0);
			MOV(R1, rB);

			BL(rA);
		}
		else
		{
			MOVI2R(rA, (u32)&Memory::Write_F64);
#if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1
			VMOV(R0, v0);
			MOV(R2, rB);
#else
			VMOV(D0, v0);
			MOV(R0, rB);
#endif
			BL(rA);
		}
		POP(4, R0, R1, R2, R3);
	}
	gpr.Unlock(rA, rB);
}
Example #23
0
void decodeInstruction(instruction_t instruction, uint32_t *dir_reg, char *dir_flags, uint8_t *SRAM, uint16_t *dec)
{
	uint8_t *R_activos=instruction.registers_list;
	/* Comparacion de mnemonic y Llamado de las funciones */
	if( strcmp(instruction.mnemonic,"ADC") == 0 || strcmp(instruction.mnemonic,"ADCS") == 0){
		dir_reg[PC]++;
		*dec=16704;
		*dec=*dec|instruction.op3_value<<3|instruction.op1_value;
		dir_reg[instruction.op1_value]=ADC(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
	}

	if( strcmp(instruction.mnemonic,"ADDS") == 0 || strcmp(instruction.mnemonic,"ADD") == 0){
		dir_reg[PC]++;
		if(instruction.op2_type=='S'){
			*dec=45056;
			dir_reg[SP]=ADD(dir_reg[SP],instruction.op3_value,dir_flags);
			*dec=*dec|instruction.op3_value;}
		else if(instruction.op3_type=='#'){
			*dec=7168;
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;
			dir_reg[instruction.op1_value]=ADD(dir_reg[instruction.op2_value], instruction.op3_value,dir_flags);
			mvprintw(4,20,"%X",*dec);}
		else{
			*dec=6144;
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;
			dir_reg[instruction.op1_value]=ADD(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);}
	}
	
	if( strcmp(instruction.mnemonic,"AND") == 0 || strcmp(instruction.mnemonic,"ANDS") == 0){
		dir_reg[PC]++;
		*dec=16384;
		if(instruction.op3_type=='#'){
			dir_reg[instruction.op1_value]=AND(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);}
		else
			dir_reg[instruction.op1_value]=AND(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"ASR") == 0 || strcmp(instruction.mnemonic,"ASRS") == 0){
		dir_reg[PC]++;
		if(instruction.op3_type=='#'){
			*dec=4096;
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;
			dir_reg[instruction.op1_value]=ASR(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);}
		else{
			*dec=16640;
			*dec=*dec|instruction.op3_value<<3|instruction.op1_value;
			dir_reg[instruction.op1_value]=ASR(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);}
	}
	
	if( strcmp(instruction.mnemonic,"BICS") == 0 || strcmp(instruction.mnemonic,"BICS") == 0){
		dir_reg[PC]++;
		if(instruction.op3_type=='#')
			dir_reg[instruction.op1_value]=BIC(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);
		else{
			*dec=17280;
			dir_reg[instruction.op1_value]=BIC(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
			*dec=*dec|instruction.op3_value<<3|instruction.op1_value;}
	}
	
	if( strcmp(instruction.mnemonic,"CMN" ) == 0 || strcmp(instruction.mnemonic,"CMNS") == 0){
		dir_reg[PC]++;
		CMN(dir_reg[instruction.op1_value], dir_reg[instruction.op2_value],dir_flags);
		*dec=17088;
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
		mvprintw(4,20,"%X",*dec);
	}
	
	if( strcmp(instruction.mnemonic,"CMP") == 0 || strcmp(instruction.mnemonic,"CMPS") == 0){
		dir_reg[PC]++;
		CMP(dir_reg[instruction.op1_value],dir_reg[instruction.op2_value],dir_flags);
		*dec=17024;
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
		mvprintw(4,20,"%X",*dec);
	}
	
	if( strcmp(instruction.mnemonic,"EOR") == 0 || strcmp(instruction.mnemonic,"EORS") == 0){
		dir_reg[PC]++;
		*dec=16448;
		if(instruction.op3_type=='#')
			dir_reg[instruction.op1_value]=EOR(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);
		else
			dir_reg[instruction.op1_value]=EOR(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"LSLS") == 0 || strcmp(instruction.mnemonic,"LSL") == 0){
		dir_reg[PC]++;
		if(instruction.op3_type=='#'){
			*dec=0;
			dir_reg[instruction.op1_value]=LSL(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
		else{
			*dec=16512;
			dir_reg[instruction.op1_value]=LSL(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
			*dec=*dec|instruction.op3_value<<3|instruction.op1_value;}
	}
	
	if( strcmp(instruction.mnemonic,"LSRS") == 0 || strcmp(instruction.mnemonic,"LSR") == 0){
		dir_reg[PC]++;
		if(instruction.op3_type=='#'){
			*dec=2048;
			dir_reg[instruction.op1_value]=LSR(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
		else{
			*dec=16576;
			dir_reg[instruction.op1_value]=LSR(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
			*dec=*dec|instruction.op3_value<<3|instruction.op1_value;}
	}
	
	if( strcmp(instruction.mnemonic,"MOV") == 0 || strcmp(instruction.mnemonic,"MOVS") == 0){
		dir_reg[PC]++;
		if(instruction.op2_type=='#'){
			*dec=8192;
			dir_reg[instruction.op1_value]=MOV(instruction.op2_value,dir_flags);
			*dec=*dec|instruction.op1_value<<8|instruction.op2_value;}
		else{
			*dec=0;
			dir_reg[instruction.op1_value]=MOV(dir_reg[instruction.op2_value],dir_flags);
			*dec=*dec|instruction.op2_value<<3|instruction.op1_value;}
	}
	
	if( strcmp(instruction.mnemonic,"MUL") == 0 || strcmp(instruction.mnemonic,"MULS") == 0){
		dir_reg[PC]++;
		*dec=17216;
		if(instruction.op3_type=='#'){
			dir_reg[instruction.op1_value]=MUL(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);}
		else{
			dir_reg[instruction.op1_value]=MUL(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
			*dec=*dec|instruction.op2_value<<3|instruction.op1_value;}
	}
	
	if( strcmp(instruction.mnemonic,"MVN") == 0 || strcmp(instruction.mnemonic,"MVNS") == 0){
		dir_reg[PC]++;
		*dec=17344;
		dir_reg[instruction.op1_value]=MVN(dir_reg[instruction.op2_value], dir_flags);
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
	}
	
	if( strcmp(instruction.mnemonic,"ORR") == 0 || strcmp(instruction.mnemonic,"ORRS") == 0){
		dir_reg[PC]++;
		*dec=17152;
		if(instruction.op3_type=='#'){
			dir_reg[instruction.op1_value]=ORR(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);}
		else{
			dir_reg[instruction.op1_value]=ORR(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
			*dec=*dec|instruction.op3_value<<3|instruction.op1_value;}
	}
	
	if( strcmp(instruction.mnemonic,"REV") == 0 || strcmp(instruction.mnemonic,"REVS") == 0){
		dir_reg[PC]++;
		*dec=47616;
		dir_reg[instruction.op1_value]=REV(dir_reg[instruction.op2_value]);
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
	}
	
	if( strcmp(instruction.mnemonic,"REVG") == 0 || strcmp(instruction.mnemonic,"REVGS") == 0){
		dir_reg[PC]++;
		*dec=47680;
		dir_reg[instruction.op1_value]=REVG(dir_reg[instruction.op2_value]);
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
	}
	
	if( strcmp(instruction.mnemonic,"REVSH") == 0 || strcmp(instruction.mnemonic,"REVSHS") == 0){
		dir_reg[PC]++;
		*dec=47808;
		dir_reg[instruction.op1_value]=REVSH(dir_reg[instruction.op2_value]);
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
	}
	
	if( strcmp(instruction.mnemonic,"ROR") == 0 || strcmp(instruction.mnemonic,"RORS") == 0){
		dir_reg[PC]++;
		*dec=16832;
		if(instruction.op3_type=='#'){
			dir_reg[instruction.op1_value]=ROR(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);}
		else{
			dir_reg[instruction.op1_value]=ROR(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
			*dec=*dec|instruction.op3_value<<3|instruction.op1_value;}
	}
	
	if( strcmp(instruction.mnemonic,"RSB") == 0 || strcmp(instruction.mnemonic,"RSBS") == 0){
		dir_reg[PC]++;
		*dec=16690;
		dir_reg[instruction.op1_value]=RSB(dir_reg[instruction.op2_value], dir_flags);
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
	}
	
	if( strcmp(instruction.mnemonic,"SBC") == 0 || strcmp(instruction.mnemonic,"SBCS") == 0){
		dir_reg[PC]++;
		*dec=16768;
		SBC(dir_reg[instruction.op1_value],dir_reg[instruction.op2_value], dir_flags);
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
	}
	
	if( strcmp(instruction.mnemonic,"SUBS") == 0 || strcmp(instruction.mnemonic,"SUB") == 0){
		dir_reg[PC]++;
		if(instruction.op2_type=='S'){
			*dec=45184;
			dir_reg[SP]=SUB(dir_reg[SP],instruction.op3_value,dir_flags);
			*dec=*dec|instruction.op3_value;}
		else if(instruction.op3_type=='#'){
			*dec=7680;
			dir_reg[instruction.op1_value]=SUB(dir_reg[instruction.op2_value],instruction.op3_value,dir_flags);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
		else{
			*dec=6656;
			dir_reg[instruction.op1_value]=SUB(dir_reg[instruction.op2_value],dir_reg[instruction.op3_value],dir_flags);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
	}
	
	if( strcmp(instruction.mnemonic,"TST") == 0 || strcmp(instruction.mnemonic,"TSTS") == 0){
		dir_reg[PC]++;
		*dec=16896;
		TST(dir_reg[instruction.op1_value], dir_reg[instruction.op2_value], dir_flags);
		*dec=*dec|instruction.op2_value<<3|instruction.op1_value;
	}
	
	if( strcmp(instruction.mnemonic,"NOP") == 0 ){
		NOP(dir_reg);
		*dec=48896;
	}
	
	if( strcmp(instruction.mnemonic,"B") == 0 ){
		*dec=57344;
		*dec=*dec|instruction.op1_value;
		B(instruction.op1_value, dir_reg);
	}
	
	if( strcmp(instruction.mnemonic,"BL") == 0 ){
		*dec=0;
		BL(instruction.op1_value, dir_reg);
	}
	
	if( strcmp(instruction.mnemonic,"BX") == 0 ){
		*dec=18176;
		BX(dir_reg);
	}
	
	if( strcmp(instruction.mnemonic,"BEQ") == 0 ){
		*dec=0;
		BEQ(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BNE") == 0 ){
		*dec=0;
		BNE(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BCS") == 0 ){
		*dec=0;
		BCS(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BCC") == 0 ){
		*dec=0;
		BCC(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BMI") == 0 ){
		*dec=0;
		BMI(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BPL") == 0 ){
		*dec=0;
		BPL(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BVS") == 0 ){
		*dec=0;
		BVS(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BVC") == 0 ){
		*dec=0;
		BVC(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BHI") == 0 ){
		*dec=0;
		BHI(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BLS") == 0 ){
		*dec=0;
		BLS(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BGE") == 0 ){
		*dec=0;
		BGE(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BLT") == 0 ){
		*dec=0;
		BLT(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BGT") == 0 ){
		*dec=0;
		BGT(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BLE") == 0 ){
		*dec=0;
		BLE(instruction.op1_value, dir_reg, dir_flags);
	}
	
	if( strcmp(instruction.mnemonic,"BAL") == 0 ){
		*dec=0;
		BAL(instruction.op1_value, dir_reg);
	}
	
	if(strcmp(instruction.mnemonic,"PUSH")==0){
		dir_reg[PC]++;
		*dec=46080;
		PUSH(SRAM, dir_reg,R_activos);
	}
	
	if(strcmp(instruction.mnemonic,"POP")==0){
		dir_reg[PC]++;
		*dec=48128;
		POP(SRAM,dir_reg,R_activos);
	}
	
	data=(uint8_t)dir_reg[instruction.op1_value];
	if(strcmp(instruction.mnemonic,"LDR")==0){
		dir_reg[PC]++;
		if(instruction.op2_type=='=' && instruction.op3_type=='N'){
			*dec=0;
			dir_reg[instruction.op1_value]=instruction.op2_value;}
		else if(instruction.op2_type=='S'){
			*dec=38912;
			dir_reg[instruction.op1_value]=LDR(dir_reg[SP], instruction.op3_value<<2, SRAM);
			*dec=*dec|instruction.op3_value|instruction.op1_value<<8;}
		else if(instruction.op3_type=='#' || instruction.op3_type=='N'){
			*dec=26624;
			if((dir_reg[instruction.op2_value]+(instruction.op3_value<<2))>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+(instruction.op3_value<<2)), &data,Read);
			else
				dir_reg[instruction.op1_value]=LDR(dir_reg[instruction.op2_value], instruction.op3_value<<2, SRAM);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value|instruction.op1_value;}
		else{
			*dec=22528;
			if((dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value])>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value]), &data,Read);
			else
				dir_reg[instruction.op1_value]=LDR(dir_reg[instruction.op2_value], dir_reg[instruction.op3_value], SRAM);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
	}
	
	if(strcmp(instruction.mnemonic,"LDRB")==0){
		dir_reg[PC]++;
		if(instruction.op3_type=='#' || instruction.op3_type=='N'){
			*dec=30720;
			if((dir_reg[instruction.op2_value]+instruction.op3_value)>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+instruction.op3_value), &data,Read);	
			else
				dir_reg[instruction.op1_value]=LDRB(dir_reg[instruction.op2_value], instruction.op3_value, SRAM);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
		else{
			*dec=23552;
			if((dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value])>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value]), &data,Read);
			else 
				dir_reg[instruction.op1_value]=LDRB(dir_reg[instruction.op2_value], dir_reg[instruction.op3_value], SRAM);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
	}
	
	if(strcmp(instruction.mnemonic,"LDRH")==0){
		dir_reg[PC]++;
		if(instruction.op3_type=='#' || instruction.op3_type=='N'){
			*dec=34816;
			if((dir_reg[instruction.op2_value]+(instruction.op3_value<<1))>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+(instruction.op3_value<<1)), &data,Read);
			else
				dir_reg[instruction.op1_value]=LDRH(dir_reg[instruction.op2_value], instruction.op3_value<<1, SRAM);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
		else{
			*dec=23040;
			if((dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value])>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value]), &data,Read);
			else
				dir_reg[instruction.op1_value]=LDRH(dir_reg[instruction.op2_value], dir_reg[instruction.op3_value], SRAM);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
	}
	
	if(strcmp(instruction.mnemonic,"LDRSB")==0){
		dir_reg[PC]++;
		*dec=22016;
		*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;
		if((dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value])>=0x40000000)
			IOAccess((uint8_t)(dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value]), &data,Read);
		else
			dir_reg[instruction.op1_value]=LDRSB(dir_reg[instruction.op2_value], dir_reg[instruction.op3_value], SRAM);
	}
	
	if(strcmp(instruction.mnemonic,"LDRSH")==0){
		dir_reg[PC]++;
		*dec=24064;
		*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;
		if((dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value])>=0x40000000)
			IOAccess((uint8_t)(dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value]), &data,Read);
		else
			dir_reg[instruction.op1_value]=LDRSH(dir_reg[instruction.op2_value], dir_reg[instruction.op3_value], SRAM);
	}
	
	if(strcmp(instruction.mnemonic,"STR")==0){
		dir_reg[PC]++;
		if(instruction.op2_type=='S'){
			*dec=38912;
			STR(dir_reg[instruction.op1_value],dir_reg[SP], instruction.op3_value<<2, SRAM);
			*dec=*dec|instruction.op3_value|instruction.op1_value<<8;}
		else if(instruction.op3_type=='#' || instruction.op3_type=='N'){
			*dec=24576;
			if((dir_reg[instruction.op2_value]+(instruction.op3_value<<2))>=0x40000000){
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+(instruction.op3_value<<2)), &data,Write);}
			else{
				STR(dir_reg[instruction.op1_value], dir_reg[instruction.op2_value], instruction.op3_value<<2, SRAM);}
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;
			mvprintw(1,3,"Hola");}
		else{
			*dec=20480;
			if((dir_reg[instruction.op2_value]+dir_reg[instruction.op2_value])>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+(dir_reg[instruction.op3_value])), &data,Write);
			else{
				STR(dir_reg[instruction.op1_value], instruction.op2_value, instruction.op3_value, SRAM);}
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
	}
	
	if(strcmp(instruction.mnemonic,"STRB")==0){
		dir_reg[PC]++;
		if(instruction.op3_type=='#' || instruction.op3_type=='N'){
			*dec=28672;
			if(dir_reg[instruction.op2_value]+instruction.op3_value>=0x40000000){
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+instruction.op3_value), &data,Write);}
			else{			
				STRB(dir_reg[instruction.op1_value], dir_reg[instruction.op2_value], instruction.op3_value, SRAM);}
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
		else{
			*dec=21504;
			if((dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value])>=0x40000000){
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+(dir_reg[instruction.op3_value])), &data,Write);}
			else{
				STRB(dir_reg[instruction.op1_value], dir_reg[instruction.op2_value], dir_reg[instruction.op3_value], SRAM);}
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
	}
	
	if(strcmp(instruction.mnemonic,"STRH")==0){
		dir_reg[PC]++;
		if(instruction.op3_type=='#' || instruction.op3_type=='N'){
			*dec=32768;
			if(((dir_reg[instruction.op2_value])+(instruction.op3_value<<1))>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+(instruction.op3_value<<1)),&data,Write);
			else
				STRH(dir_reg[instruction.op1_value], dir_reg[instruction.op2_value], instruction.op3_value<<1, SRAM);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
		else{
			*dec=20992;
			if((dir_reg[instruction.op2_value]+dir_reg[instruction.op3_value])>=0x40000000)
				IOAccess((uint8_t)(dir_reg[instruction.op2_value]+(dir_reg[instruction.op3_value])), &data,Write);
			else
				STRH(dir_reg[instruction.op1_value], dir_reg[instruction.op2_value], dir_reg[instruction.op3_value], SRAM);
			*dec=*dec|instruction.op3_value<<6|instruction.op2_value<<3|instruction.op1_value;}
	}
}
Example #24
0
/*
typedef struct
{
	char mnemonic[10];
	char op1_type; // reconoce una r o un numeral
	char op2_type;
	char op3_type;
	uint32_t op1_value; guarda el numero del registro o el valor del inmediato
	uint32_t op2_value;
	uint32_t op3_value;
}instruction_t;
*/
void decodeInstruction(instruction_t instruction,uint32_t* Rd, uint32_t* Rm, uint32_t* Rr, bool flg[], int*pc, uint8_t pila)// recibe el retorno de getInstruccion
{    uint32_t cero=0;

	if( strcmp(instruction.mnemonic,"PUSH") == 0 )
        {

	    } else

	if( strcmp(instruction.mnemonic,"ADD") == 0)
        {
           if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
           ADD(Rd[instruction.op1_value],Rm[instruction.op2_value],Rr[instruction.op3_value],flg,&pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
           ADD(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&instruction.op3_value,flg, &pc);
        }else

	    if( strcmp(instruction.mnemonic,"AND") == 0)
        {
        if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
           AND(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&Rr[instruction.op3_value],&flg[0], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
           AND(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value,&flg[0], &pc);
	    } else
	 if( strcmp(instruction.mnemonic,"ASRS") == 0 )
        {
		if((instruction.op1_type=='R')&&(instruction.op2_type=='R'))
		{
           ASRS(&Rd[instruction.op1_value],&Rm[instruction.op2_value], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='#'))
           ASRS(&Rd[instruction.op1_value],instruction.op2_value, &pc);
        } else
     if( strcmp(instruction.mnemonic,"BIC") == 0 )
        {
		if((instruction.op1_type=='R')&&(instruction.op2_type=='R'))
		{
           BIC(&Rd[instruction.op1_value],&Rm[instruction.op2_value], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='#'))
           BIC(&Rd[instruction.op1_value],instruction.op2_value, &pc);
        } else
	 if( strcmp(instruction.mnemonic,"CMN") == 0)
        {
		if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
        CMN(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&Rr[instruction.op3_value], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
        CMN(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value, &pc);
        } else
	 if( strcmp(instruction.mnemonic,"CMP") == 0 )
        {
		if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
        CMP(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&Rr[instruction.op3_value], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
        CMP(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value, &pc);
		} else
	 if( strcmp(instruction.mnemonic,"EOR") == 0)
        {if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
           EOR(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&Rr[instruction.op3_value],&flg[0], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
           EOR(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value,&flg[0], &pc);
		} else
	 if( strcmp(instruction.mnemonic,"LSL") == 0 )
        {if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
         LSL(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value, &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
         LSL(&Rd[instruction.op1_value],&Rm[instruction.op2_value],cero, &pc);

	    } else
     if( strcmp(instruction.mnemonic,"LSR") == 0)
        {
        {if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
         LSR(&Rd[instruction.op1_value],&Rm[instruction.op2_value],cero, &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
         LSR(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value, &pc);
        }
        } else
	 if( strcmp(instruction.mnemonic,"MOV") == 0)
        {
          if((instruction.op1_type=='R')&&(instruction.op2_type=='R'))
		{
         MOV(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&flg[0], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='#'))
         MOV(&Rd[instruction.op1_value],instruction.op2_value,&flg[0], &pc);
	    } else
	 if( strcmp(instruction.mnemonic,"MUL") == 0)
        {

        if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
           MUL(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&Rr[instruction.op3_value],&flg[0], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
           MUL(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value,&flg[0], &pc);

	    } else
     if(strcmp(instruction.mnemonic,"MVN") == 0)
        {
        if((instruction.op1_type=='R')&&(instruction.op2_type=='R'))
		{
         MVN(&Rd[instruction.op1_value],&Rm[instruction.op2_value], &pc);
        /* solo opera registros
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='#'))
         LSL(&Rd[instruction.op1_value],&instruction.op2_value);
	    }
	    */
	    }
	    } else
	 if(strcmp(instruction.mnemonic,"NOP") == 0 )
        {
		NOP( &pc);
	    }
	    else
     if(strcmp(instruction.mnemonic,"OR") == 0)
        {
        if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
        OR(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&Rr[instruction.op3_value],&flg[0], &pc);
        }else
        if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
        OR(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value,&flg[0], &pc);
	    } else

	 if( strcmp(instruction.mnemonic,"REV") == 0 )  //1
        {
		// instruction.op1_value --> Valor primer operando
		// instruction.op1_type  --> Tipo primer operando (R->Registro #->Numero N->Ninguno)
		// ... Igual para los otros operandos

	    } else
     if( strcmp(instruction.mnemonic,"REV16") == 0 ) //2
        {
		// instruction.op1_value --> Valor primer operando
		// instruction.op1_type  --> Tipo primer operando (R->Registro #->Numero N->Ninguno)
		// ... Igual para los otros operandos

	    } else
	 if( strcmp(instruction.mnemonic,"REVSH") == 0 )//3
        {
		// instruction.op1_value --> Valor primer operando
		// instruction.op1_type  --> Tipo primer operando (R->Registro #->Numero N->Ninguno)
		// ... Igual para los otros operandos

	    } else

	 if( strcmp(instruction.mnemonic,"ROR") == 0 )
        {
		if((instruction.op1_type=='R')&&(instruction.op2_type=='R'))
		{
        ROR(&Rd[instruction.op1_value],&Rm[instruction.op2_value], &pc);
	    }
	    } else

	 if( strcmp(instruction.mnemonic,"RSBS") == 0 )
        {
         if((instruction.op1_type=='R')&&(instruction.op2_type=='R'))
		{
        RSBS(&Rd[instruction.op1_value],&Rm[instruction.op2_value], &pc);
        }else
        if((instruction.op1_type=='R')&&instruction.op2_type=='#')
        RSBS(&Rd[instruction.op1_value],instruction.op2_value, &pc);
	    } else
	 /*if( strcmp(instruction.mnemonic,"SBC") == 0 ) //4
        {
	    } else*/
	 if( strcmp(instruction.mnemonic,"SUB") == 0 )
        {
        if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
		{
         SUB(&Rd[instruction.op1_value],&Rm[instruction.op2_value],&Rr[instruction.op3_value],&flg[0], &pc);
        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
         SUB(&Rd[instruction.op1_value],&Rm[instruction.op2_value],instruction.op3_value,&flg[0], &pc);
	    } else
	 if( strcmp(instruction.mnemonic,"LDR") == 0) //5
        {   if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='#'))
            {
                LDR(&Rd[instruction.op1_value],Rm[instruction.op1_value],instruction.op3_value);
            }else if ((instruction.op1_type=='R')&&(instruction.op2_type=='S')&&(instruction.op3_type=='#'))
	        {
	            LDR(&Rd[instruction.op1_value],pila,instruction.op3_value);
	        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='P')&&(instruction.op3_type=='#'))
	        {
	          LDR(&Rd[instruction.op1_value],pc,instruction.op3_value);
	        }else if((instruction.op1_type=='R')&&(instruction.op2_type=='R')&&(instruction.op3_type=='R'))
	        {LDR(&Rd[instruction.op1_value],Rd[instruction.op2_value],instruction.op3_value);
	        }
	    }else
	    if( strcmp(instruction.mnemonic,"LDR") == 0)
        {




}

}