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 */
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(); }