コード例 #1
0
/* Writes instructions during the assembler's first pass to OUTPUT. The case
   for general instructions has already been completed, but you need to write
   code to translate the li and other pseudoinstructions. Your pseudoinstruction 
   expansions should not have any side effects.

   NAME is the name of the instruction, ARGS is an array of the arguments, and
   NUM_ARGS specifies the number of items in ARGS.

   Error checking for regular instructions are done in pass two. However, for
   pseudoinstructions, you must make sure that ARGS contains the correct number
   of arguments. You do NOT need to check whether the registers / label are 
   valid, since that will be checked in part two.

   Also for li:
    - make sure that the number is representable by 32 bits. (Hint: the number 
        can be both signed or unsigned).
    - if the immediate can fit in the imm field of an addiu instruction, then
        expand li into a single addiu instruction. Otherwise, expand it into 
        a lui-ori pair.

    For mul, quo, and rem, the expansions should be pretty straight forward if 
    you paid attention to the lecture slides about the subtleties of $hi and $lo
    registers.

   MARS has slightly different translation rules for li, and it allows numbers
   larger than the largest 32 bit number to be loaded with li. You should follow
   the above rules if MARS behaves differently.

   Use fprintf() to write. If writing multiple instructions, make sure that 
   each instruction is on a different line.

   Returns the number of instructions written (so 0 if there were any errors).
 */
unsigned write_pass_one(FILE* output, const char* name, char** args, int num_args) {
    if (strcmp(name, "li") == 0) {
        /* YOUR CODE HERE */
      long int imm;
      if (translate_num(&imm, args[1], INT32_MIN, UINT32_MAX) == -1) {
        fprintf(stderr, "%s Number is more than 32 bits. \n", args[1]);
        return 0;
      }
      int err = translate_num(&imm, args[1], INT16_MIN, INT16_MAX);
      if (err == 0) {
        printf("optimization \n");
        fprintf(output, "addiu %s $0 %s\n", args[0], args[1]);
        return 1;
      } else {
        //lui
        int upper = imm >> 16;
        fprintf(output, "lui $at %d\n", upper);

        // ori
        int lower;
        lower = imm & 0xffff;
        fprintf(output, "ori %s $at %d\n", args[0], lower);
        return 2;
      }
    } else if (strcmp(name, "mul") == 0) {
コード例 #2
0
ファイル: mytest.c プロジェクト: timkchan/mipsAssemblerLinker
int main(int argc, char **argv) {

	freopen("null", "w", stderr); //Uncomment to show stderr.

//TEST translate_num
	char num[] = "0x6fffff";
	long int result = 0;
	int flag;

	//nornmal test.
	flag = translate_num(&result, num, 0, 999999999);
	assert(7340031 == result);
	assert(flag == 0);

	//out of bound.
	flag = translate_num(&result, num, 1, 2);
	assert(7340031 == result);
	assert(flag == -1);

	//invalid output pointer.
	flag = translate_num(NULL, num, 0, 999999999);
	assert(flag == -1);
	printf("PASSED: translate_num.\n");

//TEST add_to_table
	//uniqueTable:
	//tim1 4
	//tim2 8
	//tim3 12
	//tim4 16
	//tim5 20
	//tim6 24

	char* tim1 = "tim1";
	char* tim2 = "tim2";
	char* tim3 = "tim3";
	char* tim4 = "tim4";
	char* tim5 = "tim5";
	char* tim6 = "tim6";

	SymbolTable * uniqueTable = create_table(SYMTBL_UNIQUE_NAME);
	add_to_table(uniqueTable, tim1, 4);
	add_to_table(uniqueTable, tim2, 8);
	add_to_table(uniqueTable, tim3, 12);
	add_to_table(uniqueTable, tim4, 16);
	//normal.
	flag = add_to_table(uniqueTable, tim5, 20);
	assert(uniqueTable->len == 5);
	//name duplicate.
	flag = add_to_table(uniqueTable, tim5, 20);
	assert(flag == -1);
	//address not aligned.
	flag = add_to_table(uniqueTable, tim6, 1);
	assert(flag == -1);
	printf("2 expected errors are supressed above.\n");
	printf("Uncomment line 19 to see error msg.\n");

	flag = add_to_table(uniqueTable, tim6, 24);
	assert(uniqueTable->len == 6);
	assert(uniqueTable->cap == 10);

	//RUNNING valGrind here to expect a memory leak.
	//	./run-valgrind ./mytest
	printf("PASSED: add_to_table.\n");

//TEST free_table
	free_table(uniqueTable);
	//RUNNING valGrind here to expect the memory leak is fixed.
	//	./run-valgrind ./mytest
	printf("PASSED: free_table.\n");

//
	long int output;
	printf("%d\n", translate_num(&output, "35x", -100, 100));
	printf("%ld\n", output);

return 0;
}