Exemplo n.º 1
0
int asm_invert(ulong *res, ulong *b)  /* inverts b mod N */
{
  long i, f1, len;
  ulong t1[NMAX_ULONGS], t2[NMAX_ULONGS];
  ulong v1[NMAX_ULONGS], v2[NMAX_ULONGS];
  ulong n_half[NMAX_ULONGS];

  for (i=0; i<montgomery_ulongs; i++) if (b[i]) break;
  if (i>=montgomery_ulongs) return 0;
  if (b[0]&1) {
    asm_copy(t1,b); f1=0;
  } else {
    asm_sub(t1,montgomery_modulo_n,b); f1=1;
  }
  asm_zero(t2); t2[0]=1;
  asm_copy(v1,montgomery_modulo_n); asm_zero(v2);
  len=montgomery_ulongs-1;
  while (1) {
    if (!(t1[len]|v1[len])) len--;
    for (i=len; i>=0; i--) if (t1[i]!=v1[i]) break;
    if (i<0) break;
    if (t1[i]>v1[i]) {  /* t1>v1 */
      asm_sub_n(t1,v1); /* t1 even */
      asm_sub(t2,t2,v2);
      do {
        for (i=0; i<len; i++) t1[i]=(t1[i]>>1)|(t1[i+1]<<31);
        t1[len]>>=1;
        asm_half(t2);
      } while (!(t1[0]&1));
    } else {  /* v1>t1 */
Exemplo n.º 2
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();
}