Beispiel #1
0
instruction *
instruction_alloc( const char *name, int len, const char *val )
{
	instruction *i;

	if (!name || !val)
		return NULL;

	i = malloc( sizeof *i );
	if (!i)
		return NULL;

	if (strlen( name ) > MAXLEN_INSTRUCTION)
		printf( _("Warning: Instruction name too long\n") );
	strncpy( i->name, name, MAXLEN_INSTRUCTION );
	i->name[MAXLEN_INSTRUCTION] = '\0';

	i->value = register_alloc( len );
	if (!i->value) {
		free( i );
		return NULL;
	}
	i->out = register_alloc( len );
	if (!i->out) {
		free( i->value );
		free( i );
		return NULL;
	}

	register_init( i->value, val );
	i->data_register = NULL;
	i->next = NULL;

	return i;
}
Beispiel #2
0
void
discovery( chain_t *chain )
{
    int irlen;
    tap_register *ir;
    tap_register *irz;

    /* detecting IR size */
    jtag_reset( chain );

    printf( _("Detecting IR length ... ") );
    fflush( stdout );

    tap_capture_ir( chain );
    irlen = detect_register_size( chain );

    printf( _("%d\n"), irlen );

    if (irlen < 1) {
        printf( _("Error: Invalid IR length!\n") );
        return;
    }

    /* all 1 is BYPASS in all parts, so DR length gives number of parts */
    ir = register_fill( register_alloc( irlen ), 1 );
    irz = register_duplicate( ir );

    if (!ir || !irz) {
        register_free( ir );
        register_free( irz );
        printf( _("Error: Out of memory!\n") );
        return;
    }

    for (;;) {
        int rs;

        jtag_reset( chain );

        tap_capture_ir( chain );
        tap_shift_register( chain, ir, NULL, 1 );

        printf( _("Detecting DR length for IR %s ... "), register_get_string( ir ) );
        fflush( stdout );

        tap_capture_dr( chain );
        rs = detect_register_size( chain );

        printf( _("%d\n"), rs );

        register_inc( ir );
        if (register_compare( ir, irz ) == 0)
            break;
    }
    register_free( ir );
    register_free( irz );
}
Beispiel #3
0
data_register *
data_register_alloc( const char *name, int len )
{
	data_register *dr;

	if (!name)
		return NULL;

	dr = malloc( sizeof *dr );
	if (!dr)
		return NULL;

	if (strlen( name ) > MAXLEN_DATA_REGISTER)
		printf( _("Warning: Data register name too long\n") );
	strncpy( dr->name, name, MAXLEN_DATA_REGISTER );
	dr->name[MAXLEN_DATA_REGISTER] = '\0';

	if (len>0)
	{
		dr->in = register_alloc( len );
		dr->out = register_alloc( len );
	}
	else
	{
		dr->in = register_alloc( 1 );
		dr->out = register_alloc( 1 );
	}
	if (!dr->in || !dr->out) {
		free( dr->in );
		free( dr->out );
		free( dr->name );
		free( dr );
		return NULL;
	}

	dr->next = NULL;

	return dr;
}
Beispiel #4
0
void expr_codegen(struct expr *e, FILE *file) {
	int string_count = 0, found = 0, count = 1;
	struct string_node *sn;
	char* string_label = (char*)malloc(9);
	char* label_name = (char*)malloc(9);
	struct expr *temp_ptr;
	if(!e) return;
	switch(e->kind) {
		case EXPR_LIST:
			break;
		case EXPR_ASSIGNMENT:
			expr_codegen(e->right, file);
			fprintf(file, "\tMOV %s, %s\t\t# Assignment\n", register_name(e->right->reg), symbol_code(e->left->symbol));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_OR:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tOR %s, %s\n", register_name(e->left->reg), register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_AND:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tAND %s, %s\n", register_name(e->left->reg), register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_LT:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			sprintf(label_name, "done_%d", labelNum);
			fprintf(file, "\tJG %s\n", label_name);
			fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg));
			fprintf(file, "%s:\n", label_name);
			e->reg = e->right->reg;
			register_free(e->left->reg);
			labelNum++;
			break;
		case EXPR_GT:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			sprintf(label_name, "done_%d", labelNum);
			fprintf(file, "\tJL %s\n", label_name);
			fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg));
			fprintf(file, "%s:\n", label_name);
			e->reg = e->right->reg;
			register_free(e->left->reg);
			labelNum++;
			break;
		case EXPR_LE:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			sprintf(label_name, "done_%d", labelNum);
			fprintf(file, "\tJGE %s\n", label_name);
			fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg));
			fprintf(file, "%s:\n", label_name);
			e->reg = e->right->reg;
			register_free(e->left->reg);
			labelNum++;
			break;
		case EXPR_GE:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			sprintf(label_name, "done_%d", labelNum);
			fprintf(file, "\tJLE %s\n", label_name);
			fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg));
			fprintf(file, "%s:\n", label_name);
			e->reg = e->right->reg;
			register_free(e->left->reg);
			labelNum++;
			break;
		case EXPR_NOT_EQUALS:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			sprintf(label_name, "done_%d", labelNum);
			fprintf(file, "\tJNE %s\n", label_name);
			fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg));
			fprintf(file, "%s:\n", label_name);
			e->reg = e->right->reg;
			register_free(e->left->reg);
			labelNum++;
			break;
		case EXPR_EQUALS:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg));
			sprintf(label_name, "done_%d", labelNum);
			fprintf(file, "\tJE %s\n", label_name);
			fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg));
			fprintf(file, "%s:\n", label_name);
			e->reg = e->right->reg;
			register_free(e->left->reg);
			labelNum++;
			break;
		case EXPR_ADD:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tADD %s, %s\n", register_name(e->left->reg), register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_MINUS:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tSUB %s, %s\n", register_name(e->right->reg), register_name(e->left->reg));
			e->reg = e->left->reg;
			register_free(e->right->reg);
			break;
		case EXPR_TIMES:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tMOV %s, %rax\t\t#Move left value into rax to prepare for multiplying\n", register_name(e->left->reg));
			fprintf(file, "\tIMUL %s\t\t# Multiply %rax by the value in %s\n", register_name(e->right->reg), register_name(e->right->reg));
			fprintf(file, "\tMOV %rax, %s\t\t# Move multiplied result back to non-scratch register\n", register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_DIVIDES:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tMOVQ %s, %rax\t\t#Move left value into rax to prepare for dividing\n", register_name(e->left->reg));
			fprintf(file, "\tCQTO\n");
			fprintf(file, "\tIDIVQ %s\t\t\t# Divide %rax by the value in %s\n", register_name(e->right->reg), register_name(e->right->reg));
			fprintf(file, "\tMOVQ %rax, %s\t\t# Move divided result back to non-scratch register\n", register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_MOD:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tMOVQ %s, %rax\t\t#Move left value into rax to prepare for dividing\n", register_name(e->left->reg));
			fprintf(file, "\tCQTO\n");
			fprintf(file, "\tIDIVQ %s\t\t\t# Divide %rax by the value in %s\n", register_name(e->right->reg), register_name(e->right->reg));
			fprintf(file, "\tMOVQ %rdx, %s\t\t# Move remainder back to non-scratch register\n", register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_POWER:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\tMOV %s, %rdi\t\t# Move first argument for base of power\n", register_name(e->left->reg));
			fprintf(file, "\tMOV %s, %rsi\t\t# Move second argument for exponent\n", register_name(e->right->reg));
			fprintf(file, "\n\tPUSHQ %r10\n");
			fprintf(file, "\tPUSHQ %r11\n");
			fprintf(file, "\n\tCALL integer_power\n\n");
			fprintf(file, "\tPOPQ %r11\n");
			fprintf(file, "\tPOPQ %r10\n");
			fprintf(file, "\tMOV %rax, %s\t\t# Move result of integer_power into register\n", register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_NEGATIVE:
			expr_codegen(e->right, file);
			fprintf(file, "\tNEG %s\t\t# Negate the value\n", register_name(e->right->reg));
			e->reg = e->right->reg;
			break;
		case EXPR_NOT:
			expr_codegen(e->right, file);
			fprintf(file, "\tSUB $1, %s\t\t# Negate the boolean\n", register_name(e->right->reg));
			e->reg = e->right->reg;
			break;
		case EXPR_PRE_INCREMENT:
			expr_codegen(e->right, file);
			fprintf(file, "\tINC %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV %s, %s\n", register_name(e->right->reg), symbol_code(e->right->symbol));
			e->reg = e->right->reg;
			break;
		case EXPR_PRE_DECREMENT:
			expr_codegen(e->right, file);
			fprintf(file, "\tDEC %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV %s, %s\n", register_name(e->right->reg), symbol_code(e->right->symbol));
			e->reg = e->right->reg;
			break;
		case EXPR_POST_INCREMENT:
			// TODO: Delay incrementing
			expr_codegen(e->left, file);
			fprintf(file, "\tINC %s\n", register_name(e->left->reg));
			fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), symbol_code(e->left->symbol));
			e->reg = e->left->reg;
			break;
		case EXPR_POST_DECREMENT:
			expr_codegen(e->left, file);
			fprintf(file, "\tDEC %s\n", register_name(e->left->reg));
			fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), symbol_code(e->left->symbol));
			e->reg = e->left->reg;
			break;
		case EXPR_FUNCTION:
			// setup function args
			fprintf(file, "\tMOV $0, %rax\n");
			temp_ptr = e->right;			
			while(temp_ptr) {
				if(count > 6) {
					printf("You may only supple 6 arguments to a function\n");
					exit(1);
				}
				expr_codegen(temp_ptr->left, file);
				fprintf(file, "\tMOV %s, %s\n", register_name(temp_ptr->left->reg), num_to_arg(count++));
				temp_ptr = temp_ptr->right;
			}

			// call function
			fprintf(file, "\n\tPUSH %r10\n");
			fprintf(file, "\tPUSH %r11\n");
			fprintf(file, "\n\tCALL %s\n\n", e->left->name);
			fprintf(file, "\tPOP %r11\n");
			fprintf(file, "\tPOP %r10\n");
			e->reg = register_alloc();
			fprintf(file, "\tMOV %rax, %s\n", register_name(e->reg));
			break;
		case EXPR_BOOLEAN:
			e->reg = register_alloc();			
			fprintf(file, "\tMOV $%d,  %s\n", e->literal_value, register_name(e->reg));
			break;
		case EXPR_INT:
			e->reg = register_alloc();			
			fprintf(file, "\tMOV $%d,  %s\n", e->literal_value, register_name(e->reg));
			break;
		case EXPR_CHAR:
			e->reg = register_alloc();			
			fprintf(file, "\tMOV $%d,  %s\n", e->literal_value, register_name(e->reg));
			break;
		case EXPR_STRING:
			e->reg = register_alloc();
			// find the string
			sn = string_head;
			while(sn) {
				if(!strcmp(sn->text, e->string_literal)) {
					// string found
					found = 1;
					sprintf(string_label, "LC%d", string_count);
					e->reg = register_alloc();
					fprintf(file, "\tMOV $%s, %s\t\t# Move string into register\n", string_label, register_name(e->reg));
					break;
				}
				string_count++;
				sn = sn->next;
			}
			if(!found) {
				printf("Could not find string %s in data\n", e->string_literal);
				exit(1);
			}
			break;
		case EXPR_NAME:
			e->reg = register_alloc();
			fprintf(file, "\tMOV %s, %s\n", symbol_code(e->symbol), register_name(e->reg));
			break;
		case EXPR_ARRAY:
			break;
		case EXPR_ARRAY_LITERAL:
			break;	
	}
}
Beispiel #5
0
int
detect_register_size( chain_t *chain )
{
    int len;
    tap_register *rz;
    tap_register *rout;
    tap_register *rpat;

    /* This seems to be a good place to check if TDO changes at all */
    int tdo, tdo_stuck = -2;

    for (len = 1; len <= MAX_REGISTER_LENGTH; len++) {
        int p;
        int ok = 0;

        rz = register_fill( register_alloc( len ), 0 );
        rout = register_alloc( DETECT_PATTERN_SIZE + len );
        rpat = register_inc( register_fill( register_alloc( DETECT_PATTERN_SIZE + len ), 0 ) );

        for (p = 1; p < (1 << DETECT_PATTERN_SIZE); p++) {
            int i;
            const char *s;
            ok = 0;

            s = register_get_string( rpat );
            while (*s)
                s++;

            for (i = 0; i < TEST_COUNT; i++) {
                tap_shift_register( chain, rz, NULL, 0 );
                tap_shift_register( chain, rpat, rout, 0 );

#ifdef VERY_LOW_LEVEL_DEBUG
                printf(">>> %s\n", register_get_string(rz));
                printf("  + %s\n", register_get_string(rpat));
#endif
                tdo = register_all_bits_same_value(rout);
                if(tdo_stuck == -2) tdo_stuck = tdo;
                if(tdo_stuck != tdo) tdo_stuck = -1;

                register_shift_right( rout, len );
                if (register_compare( rpat, rout ) == 0)
                    ok++;
#ifdef VERY_LOW_LEVEL_DEBUG
                printf("  = %s => %d\n", register_get_string(rout), ok);
#endif
            }
            if (100 * ok / TEST_COUNT < TEST_THRESHOLD) {
                ok = 0;
                break;
            }

            register_inc( rpat );
        }

        register_free( rz );
        register_free( rout );
        register_free( rpat );

        if (ok)
            return len;
    }

    if(tdo_stuck >= 0)
    {
        printf(_("Warning: TDO seems to be stuck at %d\n"), tdo_stuck);
    }

    return -1;
}
Beispiel #6
0
void compare(struct expr *e, FILE *file) {
	expr_codegen(e->left, file);
	expr_codegen(e->right, file);
	e->reg = register_alloc();
	
	if(expr_typecheck(e->left)->kind==TYPE_STRING && expr_typecheck(e->right)->kind==TYPE_STRING){
		fprintf(file, "\n\t#String comparison\n");
		const char *left;
		const char *right;
		//get the correct string for left
		if(e->left->kind==EXPR_STRING_LITERAL) left = e->left->string_literal;
		else if(e->left->kind==EXPR_IDENT) left = e->left->symbol->string_literal;

		//get the correct string for right
		if(e->right->kind==EXPR_STRING_LITERAL) right = e->right->string_literal;
		else if(e->right->kind==EXPR_IDENT) right = e->right->symbol->string_literal;

		//compare the strings
		int result = strcmp(left, right);
		if(e->kind == EXPR_EQ){
			if(result){
				fprintf(file, "\tMOV $0, %s\n", register_name(e->reg));
			} else {
				fprintf(file, "\tMOV $1, %s\n", register_name(e->reg));
			}
		} else if(e->kind == EXPR_NE){
			if(result){
				fprintf(file, "\tMOV $1, %s\n", register_name(e->reg));
			} else {
				fprintf(file, "\tMOV $0, %s\n", register_name(e->reg));
			}
		}
	} else {
		fprintf(file, "\n\t#Comparison\n");
		fprintf(file, "\tCMP %s, %s\n", register_name(e->right->reg), register_name(e->left->reg));
		register_free(e->left->reg);
		register_free(e->right->reg);
		char *jump = malloc(4);
		switch(e->kind){
			case EXPR_GE:
				strcpy(jump, "JGE");
				break;
			case EXPR_LE:
				strcpy(jump, "JLE");
				break;
			case EXPR_GT:
				strcpy(jump, "JG");
				break;
			case EXPR_LT:
				strcpy(jump, "JL");
				break;
			case EXPR_EQ:
				strcpy(jump, "JE");
				break;
			case EXPR_NE:
				strcpy(jump, "JNE");
				break;
		}
		int label_true = label_count++;
		int label_false = label_count++;
		fprintf(file, "\t%s L%d\n", jump, label_true);
		fprintf(file, "\tMOV $0, %s\n", register_name(e->reg));
		fprintf(file, "\tJMP L%d\n", label_false);
		fprintf(file, "L%d:\n", label_true);
		fprintf(file, "\tMOV $1, %s\n", register_name(e->reg));
		fprintf(file, "L%d:\n", label_false);
		free(jump);
	}
}
Beispiel #7
0
//Generates code and writes it to a file
void expr_codegen(struct expr *e, FILE *file) {
	if(!e) return;
	struct expr *e2;
	switch(e->kind) {
		case EXPR_ASSIGNMENT:
			fprintf(file, "\n\t#Assignment of %s %d right value\n", e->left->symbol->name, e->left->symbol->which);
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Assignment assign to %s %d\n", e->left->symbol->name, e->left->symbol->which);
			fprintf(file, "\tMOV %s, %s\n", register_name(e->right->reg), symbol_code(e->left->symbol));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_GE: //all of these go to the compare function
		case EXPR_LE:
		case EXPR_GT:
		case EXPR_LT:
		case EXPR_EQ:
		case EXPR_NE:
			compare(e, file);
			break;
		case EXPR_ADD:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Addition\n");
			fprintf(file, "\tADD %s, %s\n", register_name(e->left->reg), register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_SUB:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Subtraction\n");
			fprintf(file, "\tSUB %s, %s\n", register_name(e->right->reg), register_name(e->left->reg));
			e->reg = e->left->reg;
			register_free(e->right->reg);
			break;
		case EXPR_MUL:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Multiplication\n");
			fprintf(file, "\tMOV %s, %%rax\n", register_name(e->left->reg));
			fprintf(file, "\tIMUL %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV %%rax, %s\n", register_name(e->right->reg));
			register_free(e->left->reg);
			e->reg = e->right->reg;
			break;
		case EXPR_DIV:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Division\n");
			fprintf(file, "\tMOV %s, %%rax\n", register_name(e->left->reg));
			fprintf(file, "\tCQO\n");
			fprintf(file, "\tIDIV %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV %%rax, %s\n", register_name(e->right->reg));
			register_free(e->left->reg);
			e->reg = e->right->reg;
			break;
		case EXPR_MOD:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Modulus\n");
			fprintf(file, "\tMOV %s, %%rax\n", register_name(e->left->reg));
			fprintf(file, "\tCQO\n");
			fprintf(file, "\tIDIV %s\n", register_name(e->right->reg));
			fprintf(file, "\tMOV %%rdx, %s\n", register_name(e->right->reg));
			register_free(e->left->reg);
			e->reg = e->right->reg;
			break;
		case EXPR_POW:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			int label_start = label_count++;
			int label_end = label_count++;
			fprintf(file, "\n\t#Exponent function\n");
			fprintf(file, "\tMOV $1, %%rax\n");
			fprintf(file, "L%d:\n", label_start);
			fprintf(file, "\tCMP $0, %s\n", register_name(e->right->reg));
			fprintf(file, "\tJE L%d\n", label_end);
			fprintf(file, "\tSUB $1, %s\n", register_name(e->right->reg));
			fprintf(file, "\tMUL %s\n", register_name(e->left->reg));
			fprintf(file, "\tJMP L%d\n", label_start);
			fprintf(file, "L%d:\n", label_end);
			register_free(e->left->reg);
			register_free(e->right->reg);
			e->reg = register_alloc();
			fprintf(file, "\tMOV %%rax, %s\n", register_name(e->reg));
			break;
		case EXPR_LOGICAL_NOT:
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Logical Not\n");
			e->reg = e->right->reg;		
			fprintf(file, "\tCMPQ $0, %s\n", register_name(e->reg));
			fprintf(file, "\tJNE L%d\n", label_count);
			fprintf(file, "\tMOV $1, %s\n", register_name(e->reg));
			fprintf(file, "\tJMP L%d\n", label_count+1);
			fprintf(file, "L%d:\n", label_count++);
			fprintf(file, "\tMOV $0, %s\n", register_name(e->reg));
			fprintf(file, "L%d:\n", label_count++);
			break;
		case EXPR_LOGICAL_AND:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Logical And\n");
			fprintf(file, "\tAND %s, %s\n", register_name(e->left->reg), register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_LOGICAL_OR:
			expr_codegen(e->left, file);
			expr_codegen(e->right, file);
			fprintf(file, "\n\t#Logical Or\n");
			fprintf(file, "\tOR %s, %s\n", register_name(e->left->reg), register_name(e->right->reg));
			e->reg = e->right->reg;
			register_free(e->left->reg);
			break;
		case EXPR_POSTFIX_PLUS:
			expr_codegen(e->left, file);
			fprintf(file, "\n\t#Increment\n");
			e->reg = register_alloc();
			fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), register_name(e->reg));
			fprintf(file, "\tADD $1, %s\n", register_name(e->left->reg));
			fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), symbol_code(e->left->symbol));
			register_free(e->left->reg);
			break;
		case EXPR_POSTFIX_MINUS:
			expr_codegen(e->left, file);
			fprintf(file, "\n\t#Increment\n");
			e->reg = register_alloc();
			fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), register_name(e->reg));
			fprintf(file, "\tSUB $1, %s\n", register_name(e->left->reg));
			fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), symbol_code(e->left->symbol));
			register_free(e->left->reg);
			break;
		case EXPR_IDENT:
			fprintf(file, "\n\t#Identifier %d %s\n", e->symbol->which, e->symbol->name);
			
			e->reg = register_alloc();
			if(e->symbol->type->kind == TYPE_STRING && e->symbol->kind == SCOPE_GLOBAL){
				fprintf(file, "\tLEA %s, %s\n", symbol_code(e->symbol), register_name(e->reg));
			} else {
				fprintf(file, "\tMOV %s, %s\n", symbol_code(e->symbol), register_name(e->reg));
			}
			break;
		case EXPR_INTEGER_LITERAL:
			//comment label
			fprintf(file, "\n\t#Integer literal %d\n", e->literal_value);

			e->reg = register_alloc();
			fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg));
			break;
		case EXPR_STRING_LITERAL:
			//comment label
			fprintf(file, "\n\t#String literal %s\n", e->string_literal);

			e->reg = register_alloc();
			fprintf(file, ".data\nSTR%d: \n.string \"%s\"\n.text\n", string_number, e->string_literal);
			fprintf(file, "\tLEA STR%d, %s\n", string_number++, register_name(e->reg));
			break;
		case EXPR_CHAR_LITERAL:
			fprintf(file, "\n\t#Char literal %c\n", e->literal_value);
			e->reg = register_alloc();
			fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg));
			break;
		case EXPR_TRUE:
			fprintf(file, "\n\t#True\n");
			e->reg = register_alloc();
			fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg));
			break;
		case EXPR_FALSE:
			fprintf(file, "\n\t#False\n");
			e->reg = register_alloc();
			fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg));
			register_free(e->reg);
			break;
		case EXPR_FCALL:
			if(function_params(e) >= 6) fcall_error();
			e->reg = register_alloc();
			fprintf(file, "\n\t#Calling function %s\n", e->left->name);
			if(!e->right){
				/* do nothing for no params */
			} else if(e->right->kind != EXPR_COMMA){ //this means single argument
				expr_codegen(e->right, file);
				fprintf(file, "\n\t#Move Only Argument\n");
				fprintf(file, "\tMOV %s, %%rdi\n", register_name(e->right->reg));
				register_free(e->right->reg);
			} else { //multiple parameters
				struct expr *param = e->right;
				int param_number = 0;
				while(param->kind == EXPR_COMMA){
					expr_codegen(param->left, file);
					fprintf(file, "\n\t#Move Argument %d\n", param_number);
					fprintf(file, "\tMOV %s, ", register_name(param->left->reg));
					register_free(param->left->reg);
					switch(param_number++){
						case 0: fprintf(file, "%%rdi"); break;
						case 1: fprintf(file, "%%rsi"); break;
						case 2: fprintf(file, "%%rdx"); break;
						case 3: fprintf(file, "%%rcx"); break;
						case 4: fprintf(file, "%%r8"); break;
						case 5: fprintf(file, "%%r9"); break;
					}	
					fprintf(file, "\n");
					param = param->right;
				}
				expr_codegen(param, file);
				fprintf(file, "\n\t#Move Argument %d\n", param_number);
				fprintf(file, "\tMOV %s, ", register_name(param->reg));
				switch(param_number++){
					case 0: fprintf(file, "%%rdi"); break;
					case 1: fprintf(file, "%%rsi"); break;
					case 2: fprintf(file, "%%rdx"); break;
					case 3: fprintf(file, "%%rcx"); break;
					case 4: fprintf(file, "%%r8"); break;
					case 5: fprintf(file, "%%r9"); break;
				}	
				fprintf(file, "\n");
				register_free(param->reg);
			}
			
			fprintf(file, "\tPUSH %%r10\n");
			fprintf(file, "\tPUSH %%r11\n");
			fprintf(file, "\n\tCALL %s\n\n", e->left->name);
			fprintf(file, "\tPOP %%r11\n");
			fprintf(file, "\tPOP %%r10\n");
			fprintf(file, "\tMOV %%rax, %s\n", register_name(e->reg));
			
			break;
		case EXPR_PARENS:
			expr_codegen(e->right, file);
			e->reg = e->right->reg;
			break;
		case EXPR_ARRCALL:	//These 4 have to do with arrays
		case EXPR_ARRINDEX:	//We are not implementing arrays for codegen
		case EXPR_BLOCK:
		case EXPR_BLOCK_COMMA:
			array_error();
			break;
	}
}
Beispiel #8
0
void* operator new[] (size_t size) {
    return register_alloc(size);
}