/*
 *	convert selection statement into tuple
		$$.tuple = tuple_selection_statement( $3.tuple, $5.tuple, 0);
		$$.tuple = tuple_selection_statement( $3.tuple, $5.tuple, $7.tuple);
 */
TUPLE	*tuple_selection_statement( TUPLE *expr, TUPLE *statement1, TUPLE *statement2)
{
	char	buffer1[ 32];
	int	length1;
	char	buffer2[ 32];
	int	length2;
	TUPLE	*tuple;

	length1 = next_label( buffer1);
	tuple = end_tuple_list( expr);
	tuple->next = new_tuple( I_BTFSC, 0x02, 0x03, MASK_ADDRESS | MASK_VALUE, 0, 0);
	tuple->next->next = new_tuple( I_GOTO, 0, 0, MASK_LABEL, buffer1, length1);
	tuple_tail_to_head( tuple, statement1);
	tuple = end_tuple_list( statement1);
	if( ! statement2)
		tuple->next = new_tuple( I_LABEL, length1, 0, MASK_LABEL, buffer1, length1);
	else
	{
		length2 = next_label( buffer2);
		tuple->next = new_tuple( I_GOTO, 0, 0, MASK_LABEL, buffer2, length2);
		tuple->next->next = new_tuple( I_LABEL, length1, 0, MASK_LABEL, buffer1, length1);
		tuple_tail_to_head( tuple, statement2);
		tuple = end_tuple_list( statement2);
		tuple->next = new_tuple( I_LABEL, length2, 0, MASK_LABEL, buffer2, length2);
	}
	return( expr);
}
Exemple #2
0
// pops a matrix that is on the stack, into the variable contained in node
static void pop_into_whole_matrix(ClmExpNode *node) {
  // TODO case where matrix on stack is actually a pointer
  char index_str[64];
  ClmSymbol *var = clm_scope_find(data.scope, node->indExp.id);
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  next_label(cmp_label);
  next_label(end_label);

  asm_pop(EAX); // pop type
  asm_pop(ECX); // pop rows
  asm_pop(EBX); // pop cols;
  // todo assert rows == A.rows && cols == A.cols
  asm_imul(ECX, EBX); // ecx now contains rows * cols
  asm_dec(ECX);

  asm_label(cmp_label);
  asm_cmp(ECX, "0");
  asm_jmp_l(end_label);

  asm_mov(EAX, ECX);
  asm_imul(EAX, "4");

  load_var_location(var, index_str, 12, EAX);
  asm_pop(index_str);

  asm_dec(ECX);
  asm_jmp(cmp_label);
  asm_label(end_label);
}
Exemple #3
0
/*
 * allocate a quad5 function
     $$.quad = new_quad5( IFTRUE, $3.quad, $5.quad, 0);       // if
     $$.quad = new_quad5( IFTRUE, $3.quad, $5.quad, $7.quad); // if else
 */
QUAD *new_quad5( int operator, QUAD *q1, QUAD *q2, QUAD *q3)
{
  QUAD *me;
  QUAD *last1 = end_quad_list( q1);
  QUAD *last2 = end_quad_list( q2);
  QUAD *label1 = new_quad( LABEL, TYPE_LABEL, next_label(), 0,0, 0,0);
  QUAD *last3;
  QUAD *label2;
  QUAD *theGoto;
  if ( q3 == 0){
    me = new_quad( operator, last1->dst_type, last1->dst_index, label1->dst_type, label1->dst_index, 0, 0);
  } else {
    last3 = end_quad_list( q3);
    label2 = new_quad( LABEL, TYPE_LABEL, next_label(), 0,0, 0,0);
    theGoto = new_quad( GOTO, TYPE_LABEL, label2->dst_index, 0,0, 0,0);
    me = new_quad( operator, last1->dst_type, last1->dst_index, label1->dst_type, label1->dst_index, label2->dst_type, label2->dst_index);
  }

  last1->next = me;
  me->next    = q2;
  if ( q3 != 0){
    last2->next  = theGoto;
    theGoto->next= label1;
    label1->next = q3;
    last3->next  = label2;
  } else {
    last2->next = label1;
  }

  return q1;
}
// operator = IF
// q1 = if (bla)
// q2 = then bla
// q3 = else bla
QUAD	*new_quad5E(int operator, QUAD *q1, QUAD *q2, QUAD *q3) {
	int if_goto = next_label();
	int then_goto = next_label();
	QUAD *ifstatement, *thenstatement, *elsestatement;
	ifstatement = end_quad_list(q1);
	ifstatement->next = new_quad(operator, ifstatement->dst_type, ifstatement->dst_index, TYPE_LABEL, if_goto, 0, 0);
	ifstatement->next->next = q2;
	thenstatement = end_quad_list(ifstatement);
	thenstatement->next = new_quad(GOTO, TYPE_LABEL, then_goto, 0, 0, 0, 0);
	thenstatement->next->next = new_quad(LABEL, TYPE_LABEL, if_goto, 0, 0, 0, 0);
	thenstatement->next->next->next = q3;
	end_quad_list(q3)->next = new_quad(LABEL, TYPE_LABEL, then_goto, 0, 0, 0, 0);
	return q1;
}
Exemple #5
0
DnsQuestions ParseQuestions(const uint8_t* dns, unsigned length)
{
    DnsQuestions result;
    if(dns_isquery(dns, length))
    {
        unsigned nq = dns_numQuestions(dns, length);
        dns += 12;
        length -= 12;
        for(unsigned i=0; i < nq; ++i)
        {
            std::string name;
            while(true)
            {
                std::string label = next_label(dns, length); // updates dns, length to new values.
                if(label.empty())
                    break;
                name += label;
                name += ".";
            }
            DnsQuestion q(name);
            result.push_back(std::move(q));
        }
    } else printf("Not query\n");
    return result;
}
Exemple #6
0
static void
write_cond(tree *cond)
{
  char *end_label = NULL;

  /* else doesn't have a condition */
  if (cond->value.cond.cond != NULL) {
    end_label = next_label();
    fprintf(state.output.f, ";#CSRC %s %d\n", 
            state.srcfilename,
            cond->value.cond.cond->line_number);
    temp_number = 0;
    write_test(cond->value.cond.cond, end_label);
    if (temp_number > max_temp_number)
      max_temp_number = temp_number;
  }
  
  /* write the body of the code */
  write_statements(cond->value.cond.body);
  
  /* if there is a condition generate a label at the end of the body */
  if (cond->value.cond.cond != NULL) {
    write_label(end_label);
    if (end_label)
      free(end_label);
  }
  
  /* generate next conditional block, if there is one */
  if (cond->value.cond.next != NULL)
    write_cond(cond->value.cond.next);
}
Exemple #7
0
static void gen_while_loop(ClmStmtNode *node) {
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  next_label(cmp_label);
  next_label(end_label);

  asm_label(cmp_label);

  // don't need to store this - just evaulate every loop
  push_expression(node->whileLoopStmt.condition);
  pop_int_into(EAX);
  asm_cmp(EAX, "0");
  asm_jmp_eq(end_label);

  gen_statements(node->whileLoopStmt.body);

  asm_jmp(cmp_label);
  asm_label(end_label);
}
// operator = IF
// q1 = if (bla)
// q2 = then bla
QUAD 	*new_quad5(int operator, QUAD *q1, QUAD *q2) {
	int goto_label = next_label();
	QUAD *ifstatement, *thenstatement;
	ifstatement = end_quad_list(q1);
	ifstatement->next = new_quad(operator, ifstatement->dst_type, ifstatement->dst_index, TYPE_LABEL, goto_label, 0, 0);
	ifstatement->next->next = q2;
	thenstatement = end_quad_list(ifstatement);
	thenstatement->next = new_quad(LABEL, TYPE_LABEL, goto_label, 0, 0, 0, 0);	
	return q1;
}
Exemple #9
0
static void gen_conditional(ClmStmtNode *node) {
  push_expression(node->conditionStmt.condition);

  if (node->conditionStmt.falseBody == NULL) {
    char end_label[LABEL_SIZE];
    next_label(end_label);

    ClmScope *trueScope =
        clm_scope_find_child(data.scope, node->conditionStmt.trueBody);

    asm_pop(EAX);
    asm_cmp(EAX, "1");
    asm_jmp_neq(end_label);
    data.scope = trueScope;
    gen_statements(node->conditionStmt.trueBody);
    asm_label(end_label);

    data.scope = trueScope->parent;
  } else {
    char end_label[LABEL_SIZE];
    char false_label[LABEL_SIZE];
    next_label(end_label);
    next_label(false_label);

    ClmScope *trueScope =
        clm_scope_find_child(data.scope, node->conditionStmt.trueBody);
    ClmScope *falseScope =
        clm_scope_find_child(data.scope, node->conditionStmt.falseBody);

    asm_pop(EAX);
    asm_cmp(EAX, "1");
    asm_jmp_neq(false_label);
    data.scope = trueScope;
    gen_statements(node->conditionStmt.trueBody);
    asm_jmp(end_label);
    asm_label(false_label);
    data.scope = falseScope;
    gen_statements(node->conditionStmt.falseBody);
    asm_label(end_label);

    data.scope = falseScope->parent;
  }
}
Exemple #10
0
static void gen_for_loop(ClmStmtNode *node) {
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  next_label(cmp_label);
  next_label(end_label);

  ClmSymbol *var = clm_scope_find(data.scope, node->forLoopStmt.varId);
  char loop_var[32];
  load_var_location(var, loop_var, 4, NULL);

  // don't need to store this - just evaluate and put into loop var
  push_expression(node->forLoopStmt.start);  
  pop_int_into(loop_var);

  asm_label(cmp_label);

  // don't need to store this - just evaulate every loop
  push_expression(node->forLoopStmt.end);
  pop_int_into(EAX);
  asm_cmp(loop_var, EAX);
  asm_jmp_g(end_label);

  gen_statements(node->forLoopStmt.body);

  if (node->forLoopStmt.delta->type == EXP_TYPE_INT &&
      node->forLoopStmt.delta->ival == 1) {
    asm_inc(loop_var);
  } else if (node->forLoopStmt.delta->type == EXP_TYPE_INT &&
             node->forLoopStmt.delta->ival == -1) {
    asm_dec(loop_var);
  } else if (node->forLoopStmt.delta->type == EXP_TYPE_INT) {
    asm_add_i(loop_var, node->forLoopStmt.delta->ival);
  } else {
    push_expression(node->forLoopStmt.delta);
    asm_pop(EAX);
    asm_add(loop_var, EAX);
  }

  asm_jmp(cmp_label);
  asm_label(end_label);
}
Exemple #11
0
// pushes a matrix identified by the node onto the stack
static void push_whole_matrix(ClmExpNode *node) {
  // TODO case where matrix on stack is actually a pointer
  char index_str[64];
  ClmSymbol *var = clm_scope_find(data.scope, node->indExp.id);
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  next_label(cmp_label);
  next_label(end_label);

  LOAD_COLS(var, index_str);
  asm_mov(EDX, index_str); // edx = cols
  LOAD_ROWS(var, index_str);
  asm_mov(EBX, index_str); // ebx = rows
  asm_mov(ECX, EBX);
  asm_imul(ECX, EDX);
  asm_dec(ECX); // ecx = rows * cols - 1

  asm_label(cmp_label);
  asm_cmp(ECX, "0");
  asm_jmp_l(end_label);

  asm_mov(EAX, ECX);
  asm_imul(EAX, "4");

  load_var_location(var, index_str, 12, EAX);
  asm_push(index_str);

  asm_dec(ECX);
  asm_jmp(cmp_label);
  asm_label(end_label);

  // push type info
  asm_push(EDX); // cols
  asm_push(EBX); // rows
  asm_push_const_i((int)CLM_TYPE_MATRIX);
}
/*
 *	iteration selection statement into tuple
		$$.tuple = tuple_iteration_statement( $3.tuple, $5.tuple);
 */
TUPLE	*tuple_iteration_statement( TUPLE *expr, TUPLE *statement)
{
	char	buffer1[ 32];
	int	length1;
	char	buffer2[ 32];
	int	length2;
	TUPLE	*tuple;
	TUPLE	*tuple2;
/*
 *	create the next temporary label
 */
	length1 = next_label( buffer1);
	length2 = next_label( buffer2);
	tuple = new_tuple( I_LABEL, length1, 0, MASK_LABEL, buffer1, length1);
	tuple->next = expr;
	tuple2 = end_tuple_list( expr);
	tuple2->next = new_tuple( I_BTFSC, 0x02, 0x03, MASK_ADDRESS | MASK_VALUE, 0, 0);
	tuple2->next->next = new_tuple( I_GOTO, 0, 0, MASK_LABEL, buffer2, length2);
	tuple_tail_to_head( tuple2, statement);
	tuple2 = end_tuple_list( statement);
	tuple2->next = new_tuple( I_GOTO, 0, 0, MASK_LABEL, buffer1, length1);
	tuple2->next->next = new_tuple( I_LABEL, length2, 0, MASK_LABEL, buffer2, length2);
	return( tuple);
}
/* ******************************* *
 *  Generate the next permutation  *
 * ******************************* */
int next_sample(int *L)
{
    if(local_perm_count >= local_perm_size)
        return 0;

    // Note: local_pa.B == 0 => complete permutations
    //       local_pa.B >  0 => random permutations
    if(local_pa.B > 0) {
        get_permu(&local_pa, local_perm_count, L);
    } else {
        next_label(local_pa.n, local_pa.k, local_pa.nk, local_L);
        memcpy(L, local_L, sizeof(int) * local_pa.n);
    }

    local_perm_count++;

    return 1;
}
Exemple #14
0
static void
write_loop(tree *loop)
{
  char *start_label = NULL;

  /* write out initalization code */
  if (loop->value.loop.init != NULL) {
    write_statements(loop->value.loop.init);
  }
 
  start_label = next_label();
  write_label(start_label);

  /* write the body of the loop */
  if (loop->value.loop.body != NULL)
    write_statements(loop->value.loop.body);

  /* write the increment statements */
  if (loop->value.loop.incr != NULL)
    write_statements(loop->value.loop.incr);

  /* write the exit statements */
  if (loop->value.loop.exit != NULL) {
    fprintf(state.output.f, ";#CSRC %s %d\n", 
            state.srcfilename,
            loop->value.loop.exit->line_number);
    temp_number = 0;
    write_test(loop->value.loop.exit, start_label);
    if (temp_number > max_temp_number)
      max_temp_number = temp_number;
  } else {
    write_asm_line("goto %s", start_label);
  }

  if (start_label)
    free(start_label);
}
Exemple #15
0
// pops a matrix from the stack into a row or column of a matrix identified by
// node
static void pop_into_row_or_col(ClmExpNode *node) {
  // TODO case where matrix on stack is actually a pointer
  char index_str[64];
  ClmSymbol *var = clm_scope_find(data.scope, node->indExp.id);
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  next_label(cmp_label);
  next_label(end_label);

  // put index value into EDX
  if(node->indExp.rowIndex != NULL){
    gen_index_into(EDX, node->indExp.rowIndex);
  }else{
    gen_index_into(EDX, node->indExp.colIndex);
  }

  asm_pop(EAX); // pop type
  asm_pop(EAX); // pop rows
  asm_pop(EBX); // pop cols
  // todo assert rows == A.rows or cols == A.cols

  asm_mov(ECX, "0");

  if (node->indExp.rowIndex != NULL) {
    /*
      A[x,]
      for i in 1..A.cols do
        A[x * A.cols + i] = pop
      end
    */
    LOAD_COLS(var, index_str);
    asm_imul(EDX, index_str);

    asm_label(cmp_label);
    asm_cmp(ECX, index_str);
    asm_jmp_eq(end_label);

    asm_mov(EAX, EDX);
    asm_add(EAX, ECX); // eax now contains rowIndex * A.cols + i
    asm_imul(EAX, "4");
    load_var_location(var, index_str, 12, EAX);
    asm_pop(index_str);
  } else {
    /*
      A[,y]
      for i in 1..A.rows do
        A[i * A.cols + y] = pop
      end
    */
    LOAD_ROWS(var, index_str);

    asm_label(cmp_label);
    asm_cmp(ECX, index_str);
    asm_jmp_eq(end_label);

    asm_mov(EAX, ECX);
    asm_imul(EAX, index_str);
    asm_add(EAX, EDX);
    asm_imul(EAX, "4");
    load_var_location(var, index_str, 12, EAX);
    asm_pop(index_str);
  }

  asm_inc(ECX);
  asm_jmp(cmp_label);
  asm_label(end_label);
}
/* ******************************************************** *
 *  Create the sampling structure and initialize all values *
 * ******************************************************** */
void create_sampling(int n, int *L, int B, int generator_flag, int initial_count)
{  
    int *ordern, *permun, *myL;
    int i;

    // Set the local size of permutations
    local_perm_size = B;
    local_perm_count = 1;

    // Allocate and initialize local L to original L
    local_L = (int *)R_alloc(n, sizeof(int));

    // To check random or complete
    if( generator_flag == 1 ) {

        // Initialize the permutation array (struct)
        // Sets the B in the struct equal to 0 to be
        // able to identify the generator later on
        init_permu_array(&local_pa, L, n, 0);

        // * ================================================================= *
        // *                     Forwarding logic                              *
        // *                     ----------------                              *
        // *  For parallel executions all processes, appart from the one with  *
        // *  rank == 0, should forward their random generators in order to    *
        // *  be able to reproduce the exact same random permutations as the   *
        // *  serial version of the code (or a version with only one thread)   *
        // *                                                                   *
        // *  The code below uses the initial_count variable to "burn" the     *
        // *  cycles from the random generator                                 *
        // * ================================================================= *

        // All processes apart from process with rank == 0 (translates to
        // initial_count == 0) will perform this forward
        if ( initial_count != 0 ) {

            // Initialize label
            init_label(local_pa.n, local_pa.k, local_pa.nk, local_L);

            // Burn the cycles
            // We *must* use L in order to initialize it in the proper permutation
            // L is given as the starting position for the next permutation
            for(i=0; i < initial_count; i++) {
                next_label(local_pa.n, local_pa.k, local_pa.nk, local_L);
            }
        }

        // * ================================================================= *
        // * ================================================================= *

    } else {

        // Intiailize the permu_array (struct)
        init_permu_array(&local_pa, L, n, B);

        permun = (int *)R_alloc(local_pa.n, sizeof(int));
        ordern = (int*)R_alloc(local_pa.n, sizeof(int));
        myL = (int *)R_alloc(local_pa.n, sizeof(int));

        // * ================================================================= *
        // *                     Forwarding logic                              *
        // *                     ----------------                              *
        // *  For parallel executions all processes, appart from the one with  *
        // *  rank == 0, should forward their random generators in order to    *
        // *  be able to reproduce the exact same random permutations as the   *
        // *  serial version of the code (or a version with only one thread)   *
        // *                                                                   *
        // *  The code below uses the initial_count variable to "burn" the     *
        // *  cycles from the random generator                                 *
        // * ================================================================= *

        // Set initial seed
        set_seed(g_random_seed);

        // Burn the cycles
        // ("permun" is a safe scratch space for this)
        for(i=0; i < initial_count; i++) {
            sample(permun, n);
        }

        // * ================================================================= *
        // * ================================================================= *

        for(i=0; i<n; i++){
            ordern[i]=i;
        }

        // Allocate and assign the values for l_first_sample
        set_permu(&local_pa, 0, L);

        for(i=1; i<B; i++) {
            memcpy(permun, ordern, sizeof(int)*n);
            sample(permun, n);

            // Change to labbeling
            sample2label(n, local_pa.k, local_pa.nk, permun, myL);
            set_permu(&local_pa, i, myL);
        }


    }
}
Exemple #17
0
// pushes a row or col of the matrix identified by node onto the stack
static void push_row_or_col(ClmExpNode *node) {
  // TODO case where matrix on stack is actually a pointer
  char index_str[64];
  ClmSymbol *var = clm_scope_find(data.scope, node->indExp.id);
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  next_label(cmp_label);
  next_label(end_label);

  // put index value into EDX
  if(node->indExp.rowIndex != NULL){
    gen_index_into(EDX, node->indExp.rowIndex);
  }else{
    gen_index_into(EDX, node->indExp.colIndex);
  }

  if (node->indExp.rowIndex != NULL) {
    /*
      push A[x,]
      for i in A.cols,-1..1 do
        push A[x * A.cols + i]
      end
    */
    LOAD_COLS(var, index_str);
    asm_mov(ECX, index_str);
    asm_imul(EDX, ECX);
    asm_dec(ECX);

    asm_label(cmp_label);
    asm_cmp(ECX, "0");
    asm_jmp_l(end_label);

    asm_mov(EAX, EDX);
    asm_add(EAX, ECX); // eax = rowIndex * A.cols + i
    asm_imul(EAX, "4");
    load_var_location(var, index_str, 12, EAX);
    asm_push(index_str);
  } else {
    /*
      push A[,y]
      for i in A.rows,-1..1 do
        push A[i * A.cols + y]
      end
    */
    LOAD_ROWS(var, index_str);
    asm_mov(ECX, index_str);
    asm_dec(ECX);

    asm_label(cmp_label);
    asm_cmp(ECX, "0");
    asm_jmp_l(end_label);

    asm_mov(EAX, ECX);
    asm_imul(EAX, index_str);
    asm_add(EAX, EDX); // eax = i * A.cols + y
    asm_imul(EAX, "4");
    load_var_location(var, index_str, 12, EAX);
    asm_push(index_str);
  }

  asm_inc(ECX);
  asm_jmp(cmp_label);
  asm_label(end_label);
}
Exemple #18
0
// stack should look like this:
// val
// type
static void push_expression(ClmExpNode *node) {
  if (node == NULL)
    return;

  ClmType expression_type = clm_type_of_exp(node, data.scope);
  switch (node->type) {
  case EXP_TYPE_INT:
    asm_push_const_i(node->ival);
    asm_push_const_i((int)expression_type);
    break;
  case EXP_TYPE_FLOAT:
    asm_push_const_f(node->fval);
    asm_push_const_i((int)expression_type);
    break;
  case EXP_TYPE_STRING:
    // TODO push a string onto the stack
    break;
  case EXP_TYPE_ARITH: {
    ClmType right_type = clm_type_of_exp(node->arithExp.right, data.scope);
    ClmType left_type = clm_type_of_exp(node->arithExp.left, data.scope);
    if (left_type == CLM_TYPE_MATRIX && clm_type_is_number(right_type)) {
      // here the only ops are mul & div... we are scaling matrix
      // gen left and then right here... if we don't then we have
      // int val
      // int type
      // matrix
      // cols
      // rows
      // matrix type
      // and we have to pop the int after we generate the value... which is hard
      // and since we are multiplying the matrix in place, it would be easiest
      // to
      // gen the matrix first and then the int, so we just have to pop two
      // values
      // in total
      push_expression(node->arithExp.left);
      asm_mov(EDX, ESP);
      push_expression(node->arithExp.right);
      gen_arith(node);
    } else {
      push_expression(node->arithExp.right);
      asm_mov(EDX, ESP);
      push_expression(node->arithExp.left);
      gen_arith(node);
    }
    break;
  }
  case EXP_TYPE_BOOL:
    push_expression(node->boolExp.right);
    asm_mov(EDX, ESP);
    push_expression(node->boolExp.left);
    gen_bool(node);
    break;
  case EXP_TYPE_CALL: {
    // first push everything thats not a matrix... and for matrices push a pointer
    int tempStartID = data.temporaryID;
    int i;
    ClmExpNode *param;
    char temporary[256];

    // first for any matrices that are parameters that will be pushed through
    // the stack, push them on the stack and save their location into a temporary
    // global
    for (i = node->callExp.params->length - 1; i >= 0; i--) {
      param = node->callExp.params->data[i];
      if(param->type == CLM_TYPE_MATRIX){
        ClmLocation location = clm_location_of_exp(param, data.scope);
        switch(location){
            case LOCATION_STACK:
              push_expression(param);
              next_temporary(temporary);
              asm_mov(temporary, ESP);
              break;
            default:
              break;
        }
      }
    }

    // then push every expression.. when we get to a matrix, push the pointer
    // to its location
    int tempOffset = 1;
    char index_str[256];
    for (i = node->callExp.params->length - 1; i >= 0; i--) {
      param = node->callExp.params->data[i];
      if(param->type == CLM_TYPE_MATRIX){
        ClmLocation location = clm_location_of_exp(param, data.scope);
        switch(location){
            case LOCATION_STACK:
              sprintf(temporary, "dword [temporary%d]", tempStartID + tempOffset);
              asm_push(temporary);
              tempOffset++;
              break;
            default:
            {
              // the only way its a matrix and not on the stack is if its an
              // ind exp with no indices
              ClmSymbol *symbol = clm_scope_find(data.scope, param->indExp.id);
              load_var_location(symbol, index_str, 0, NULL);
              asm_push(index_str);
              break;
            }
        }
        asm_push_const_i((int) CLM_TYPE_MATRIX);
      }else{
        push_expression(param);
      }
    }

    asm_call(node->callExp.name);

    // TODO pop off arguments from the stack
    break;
  }
  case EXP_TYPE_INDEX:
    push_index(node);
    break;
  case EXP_TYPE_MAT_DEC: {
    int i;
    if (node->matDecExp.arr != NULL) {
      for (i = node->matDecExp.length - 1; i >= 0; i--) {
        // TODO... push f or push i?
        asm_push_const_i((int)node->matDecExp.arr[i]);
      }
      asm_push_const_i(node->matDecExp.size.cols);
      asm_push_const_i(node->matDecExp.size.rows);
      asm_push_const_i((int)CLM_TYPE_MATRIX);
    } else {
      // push a matrix onto the stack with all 0s
      char cmp_label[LABEL_SIZE];
      char end_label[LABEL_SIZE];
      next_label(cmp_label);
      next_label(end_label);

      gen_exp_size(node);
      asm_pop(EAX); // # rows
      asm_pop(EBX); // # cols

      asm_mov(ECX, EAX);
      asm_imul(ECX, EBX);
      asm_dec(ECX);
      asm_label(cmp_label);
      asm_cmp(ECX, "0");
      asm_jmp_l(end_label);
      asm_push_const_i(0);
      asm_dec(ECX);
      asm_jmp(cmp_label);
      asm_label(end_label);
      asm_push(EBX);
      asm_push(EAX);
      asm_push_const_i((int)CLM_TYPE_MATRIX);
    }
    break;
  }
  case EXP_TYPE_PARAM:
    break;
  case EXP_TYPE_UNARY:
    push_expression(node->unaryExp.node);
    gen_unary(node);
    break;
  }
}
Exemple #19
0
static void gen_func_dec(ClmStmtNode *node) {
  int i;
  char func_label[LABEL_SIZE];

  sprintf(func_label, "_%s", node->funcDecStmt.name);
  ClmScope *funcScope = clm_scope_find_child(data.scope, node);

  asm_label(func_label);
  asm_push(EBP);
  asm_mov(EBP, ESP);

  int local_var_size = 2 * 4 * (funcScope->symbols->length -
                                node->funcDecStmt.parameters->length);
  char local_var_size_str[32];
  sprintf(local_var_size_str, "%d", local_var_size);
  asm_sub(ESP, local_var_size_str);

  // each local var has 2 slots on the stack, their type and the value
  // for matrices, the value is a pointer to the location on the stack
  // these are all declared below the local variables
  ClmSymbol *sym;
  ClmExpNode *dec;
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  char index_str[32];
  for (i = 0; i < funcScope->symbols->length; i++) {
    sym = funcScope->symbols->data[i];
    dec = sym->declaration;

    if (sym->location == LOCATION_PARAMETER)
      continue;

    // setting the type of the local var
    load_var_location(sym, index_str, 0, NULL);
    asm_mov_i(index_str, (int)sym->type);

    // setting the value of the local var
    load_var_location(sym, index_str, 4, NULL);
    asm_mov_i(index_str, 0);

    if (sym->type == CLM_TYPE_MATRIX) {
      // TODO what does this do? does it work?
      next_label(cmp_label);
      next_label(end_label);

      gen_exp_size(dec);
      asm_pop(EAX); // eax contains num of rows
      asm_pop(EBX); // ebx contains num of cols
      asm_mov(ECX, EAX);
      asm_imul(ECX, EBX);
      asm_label(cmp_label);
      asm_dec(ECX);
      asm_cmp(ECX, "0");
      asm_jmp_eq(end_label);
      asm_push_const_i(0);
      asm_jmp(cmp_label);
      asm_label(end_label);
      asm_push(EBX); // cols

      // setting the pointer to point at the rows
      // note: push changes the value at esp and THEN
      // decrements it
      load_var_location(sym, index_str, 4, NULL);
      asm_mov(index_str, ESP);

      asm_push(EAX); // rows
    }
  }
  // TODO figure out strings though!

  data.inFunction = 1;
  data.scope = funcScope;
  gen_statements(node->funcDecStmt.body);
  data.scope = funcScope->parent;
  data.inFunction = 0;

  if (node->funcDecStmt.returnSize.rows == -1) {
    // no return value!
    asm_mov(ESP, EBP);
    asm_pop(EBP);
  }
  asm_ret();
}