Exemplo n.º 1
0
void test2()
{
    unsigned int a = 9;

    printf("a:\n");
    printBits(a);

    setBitAt(&a, 10, 1);

    printf("a after setBitAt(&a,10,1):\n");

    printBits(a);
    setBitAt(&a, 20, 1);

    printf("a after setBitAt(&a,20,1):\n");
    printBits(a);


    setBitAt(&a, 0, 0);
    printf("a after setBitAt(&a,0,0):\n");
    printBits(a);

    setBitAt(&a, 3, 0);
    printf("a after setBitAt(&a,3,0):\n");
    printBits(a);


}
void calcAddress(int* r, int isPreIndex, char* arg3, char* arg4, char* arg5) {
	/* POST-INDEXING
	 * It is of the following two forms
	 * [Rn], #expression
	 * [Rn], {+/-}Rm{, <shift>}
	 *
	 * PRE-INDEXING
	 * It is of the following two forms
	 * Note the bracket close in the second one
	 * [Rn, #expression]
	 * [Rn, {+/-}Rm{, <shift>}]
	*/
	if(arg3[0] == '#') {
		//#expression] form (']' depends on indexing)
		if(isPreIndex) isInClear(']', arg3, MAX_ARG_SIZE);

		int offset = strToInt(arg3, MAX_ARG_SIZE);

		//offset must fit in 12bits as signed number
		if(offset > 0x7ff || offset < ((int)(0xfffff800))) {
			printf("ERROR: Cannot fit offset value \"%d\" to 12 bits in ldr\n", offset);
			exit(EXIT_FAILURE);
		}

		//If it does continue
		int isNeg = getBitAt(&offset, 31);

		//Set U Flag, add or subtract offset
		setBitAt(r, 23, isNeg == 0);

		if(isNeg) {
			offset = -(offset);
		}

		//Set the offset
		setBitsAt(r, 0, &offset, 0, 11);

	} else {
		//{+/-}Rm{, <shift>}] ']' depends on indexing form
		//SET IFLAG as offset is a shifted register
		//NOTE OPPOSITE CASE IN SINGLE DATA TRANSFER
		if(getBitAt(r, 26)) setBitAt(r, 25, 1);

		//Is the bracket closing? If yes, then there is no shift
		//Rm] or Rm, <shift>] for pre-index
		//Rm, <shift>

		//Clear any closing brackets from Rm] in pre-indexing
		if(isPreIndex) isInClear(']', arg3, MAX_ARG_SIZE);

		//Check positive or negative and get Rm value
		int Rm;

		if(arg3[0] == '-') {
			//Set U Flag to subtract offset
			setBitAt(r, 23, 0); //subtract
			//Omit '-' when parsing
			Rm = strToInt(arg3 + 1, MAX_ARG_SIZE - 1);
		} else {
			//By default the UFLAG is set to add
			Rm = strToInt(arg3, MAX_ARG_SIZE);
		}

		//Set Rm
		setBitsAt(r, 0, &Rm, 0, 4);

		if(arg4[0] != '\0') {
			/*THERE IS SHIFTING
			* It can be 1 of the following
			* <shift> <register>]
			* <shift> <#expression>]
			* ']' depend on indexing type
			*/

			//Get and set the shift code
			int shiftCode = getShiftCode(arg4);
			setBitsAt(r, 5, &shiftCode, 0, 2);

			//get rid of closing brackets if pre-indexing
			if(isPreIndex) isInClear(']', arg5, MAX_ARG_SIZE);

			//Check the second argument to shift
			if(arg5[0] == '#') {
				//<#expression> form
				int shift_amount = strToInt(arg5, MAX_ARG_SIZE);

				//Shift amount must fit into 5 bits
				if(shift_amount > 0x1f) {
					printf("ERROR: Too large immediate shift value: %d\n", shift_amount);
					exit(EXIT_FAILURE);
				}

				//Set the shift amount
				setBitsAt(r, 7, &shift_amount, 0, 5);
			} else {
				//<register> form
				//Set register shift flag
				setBitAt(r, 4, 1);

				//Get and set Rs
				int Rs = strToInt(arg5, MAX_ARG_SIZE);
				setBitsAt(r, 8, &Rs, 0, 4);
			}
		}
	} //endof if(arg3[0] == '#') else
}